<?php

require_once("inc/read_conf.php");
require_once("inc/db.php");
require_once("inc/ssh.php");
require_once("inc/idna_convert.class.php");
require_once("inc/validate_param.php");
require_once("inc/slave_actions.php");
require_once("inc/auth.php");
require_once("inc/enc.php");
require_once("inc/ipmi_cmds.php");
require_once("inc/hardware_profile.php");
require_once("inc/auto_racking.php");
require_once("inc/plugin_dns.php");
require_once("inc/plugin_monitoring.php");
require_once("inc/plugin_root_pass.php");
require_once("inc/plugin_ipmi_pass.php");
require_once("inc/auto_provision.php");

$conf = readmyconf();
$con = connectme($conf);

function get_machine_from_serial_or_hostname($con, $conf, $serial=null){
    $json["status"] = "success";
    $json["message"] = "Successfuly queried API.";
    $json["data"] = Array();

    if( is_null($serial) ){
        if(isset($_REQUEST["serial"])){
            $safe_machine_serial = safe_serial("serial");
            $safe_machine_hostname = safe_fqdn("serial");
        }elseif(isset($_REQUEST["machine_serial"])){
            $safe_machine_serial = safe_serial("machine_serial");
            $safe_machine_hostname = safe_fqdn("machine_serial");
        }
        if($safe_machine_serial === FALSE && $safe_machine_hostname === FALSE ){
            $json["status"] = "error";
            $json["message"] = "Error: not valid chassis serial number or hostname.";
            return $json;
        }
    }else{
        $safe_machine_serial = $serial;
    }
    if($safe_machine_serial === FALSE){
        $q = "SELECT * FROM machines WHERE hostname='$safe_machine_hostname'";
    }else{
        $q = "SELECT * FROM machines WHERE serial='$safe_machine_serial'";
    }
    $r = mysqli_query($con, $q);
    if($r === FALSE){
        $json["status"] = "error";
        $json["message"] = mysqli_error($con). " doing $q";
        return $json;
    }
    $n = mysqli_num_rows($r);
    if($n != 1){
        if($safe_machine_serial !== FALSE){
            $q = "SELECT * FROM machines WHERE hostname='$safe_machine_hostname'";
            $r = mysqli_query($con, $q);
            if($r === FALSE){
                $json["status"] = "error";
                $json["message"] = mysqli_error($con). " doing $q";
                return $json;
            }
            $n = mysqli_num_rows($r);
            if($n != 1){
                $json["status"] = "error";
                $json["message"] = "Error: machine with serial or hostname $safe_machine_serial doesn't exist.";
                return $json;
            }
        }else{
            $json["status"] = "error";
            $json["message"] = "Error: machine with serial or hostname $safe_machine_serial doesn't exist.";
            return $json;
        }
    }
    $json["data"] = mysqli_fetch_array($r);
    return $json;
}

function api_actions($con,$conf){
    $json["status"] = "success";
    $json["message"] = "Successfuly queried API.";
    if(!isset($_REQUEST["action"])){
        $json["status"] = "error";
        $json["message"] = "Error: no action specified.";
        return $json;
    }

    if($_SERVER['REMOTE_ADDR'] != "::1" && $_SERVER['REMOTE_ADDR'] != "127.0.0.1"){
        // No auth param? Bye bye ... :)
        if((!isset($_REQUEST["oci_login"])) || $_REQUEST["oci_login"] == "" || (!isset($_REQUEST["oci_pass"])) || $_REQUEST["oci_pass"] == ""){
            $json["status"] = "error";
            $json["message"] = "Error: please set oci_login and oci_pass to authenticate.";
            return $json;
        }
        // Auth failed? Bye bye... :)
        $ret = oci_auth_user($con, $conf, $_REQUEST["oci_login"], $_REQUEST["oci_pass"]);
        if($ret["status"] != "success"){
            return $ret;
        }
    }

    switch($_REQUEST["action"]){
    case "enc":
        # Puppet ENC is now in src/inc/enc.php
        $json = puppet_enc($con,$conf);
        return $json;
        break;
    case "machine_show_from_hostname":
        $safe_hostname = safe_fqdn("hostname");
        $r = mysqli_query($con, "SELECT * FROM machines WHERE hostname='$safe_hostname'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "No such hostname in database.";
            return $json;
        }
        $a = mysqli_fetch_array($r);
        $json["data"] = $a;
        return $json;
        break;
    case "cluster_rolecounts_list":
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster not found.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $cluster_id = $cluster["id"];
        $q = "SELECT roles.name AS role, rolecounts.count AS count FROM roles,rolecounts WHERE rolecounts.cluster='$cluster_id' AND rolecounts.role=roles.id ORDER BY roles.name";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        $json["data"] = Array();
        for($i=0;$i<$n;$i++){
            $json["data"][] = mysqli_fetch_array($r);
        }
        return $json;
        break;
    case "cluster_show":
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster not found.";
            return $json;
        }
        $json["data"] = mysqli_fetch_array($r);

        # Get the first master serial.
        if(! is_null($json["data"]["first_master_machine_id"])){
            $machine_id = $json["data"]["first_master_machine_id"];
            $q = "SELECT serial FROM machines WHERE id='$machine_id'";
            $r = mysqli_query($con, $q);
            if($r === FALSE){
                $json["status"] = "error";
                $json["message"] = mysqli_error($con);
                return $json;
            }
            $n = mysqli_num_rows($r);
            if($n != 1){
                $json["status"] = "error";
                $json["message"] = "Error: first master serial not found in file: ".__FILE__." line: ".__LINE__.".";
                return $json;
            }
            $machine = mysqli_fetch_array($r);
            $json["data"]["first_master_machine_serial"] = $machine["serial"];
        }
        return $json;
        break;
    case "cluster_rolecounts_set":
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster not found.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $safe_cluster_id = $cluster["id"];

        $safe_role_name = safe_fqdn("role");
        if($safe_role_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid role name.";
            return $json;
        }
        $q = "SELECT * FROM roles WHERE name='$safe_role_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: role not found.";
            return $json;
        }
        $role = mysqli_fetch_array($r);
        $safe_role_id = $role["id"];

        $safe_role_count = safe_int("count");
        if($safe_role_count === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid role count.";
            return $json;
        }

        $q = "UPDATE rolecounts SET count='$safe_role_count' WHERE role='$safe_role_id' AND cluster='$safe_cluster_id'";
        $r = mysqli_query($con, $q);
        return $json;
        break;
    case "cluster_set":
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster not found.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $update = "";

        // initial_cluster_setup
        if(isset($_REQUEST["initial_cluster_setup"])){
            if($_REQUEST["initial_cluster_setup"] == "yes"){
                $safe_initial_cluster_setup = "yes";
            }else{
                $safe_initial_cluster_setup = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "initial_cluster_setup='$safe_initial_cluster_setup'";
        }

        // Swift proxy hostname
        if(isset($_REQUEST["region_name"])){
            $safe_region_name = safe_fqdn("region_name");
            if($safe_region_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid region name.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "region_name='$safe_region_name'";
        }

        // nested virtualization
        if(isset($_REQUEST["nested_virt"])){
            if($_REQUEST["nested_virt"] == "yes"){
                $safe_nested_virt = "yes";
            }else{
                $safe_nested_virt = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nested_virt='$safe_nested_virt'";
        }

        // nested virtualization
        if(isset($_REQUEST["use_ovs_ifaces"])){
            if($_REQUEST["use_ovs_ifaces"] == "yes"){
                $safe_use_ovs_ifaces = "yes";
            }else{
                $safe_use_ovs_ifaces = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "use_ovs_ifaces='$safe_use_ovs_ifaces'";
        }

        // Swift part power
        if(isset($_REQUEST["swift_part_power"])){
            $safe_swift_part_power = safe_int("swift_part_power");
            if($safe_swift_part_power === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid swift part power.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_part_power='$safe_swift_part_power'";
        }

        // Swift proxy hostname
        if(isset($_REQUEST["swift_proxy_hostname"])){
            $safe_swift_proxy_hostname = safe_fqdn("swift_proxy_hostname");
            if($safe_swift_proxy_hostname === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid swift proxy hostname.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_proxy_hostname='$safe_swift_proxy_hostname'";
        }

        // Swift encryption key ID
        if(isset($_REQUEST["swift_encryption_key_id"])){
            $safe_swift_encryption_key_id = safe_uuid("swift_encryption_key_id");
            if($safe_swift_encryption_key_id === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: swift_encryption_key_id is not an UUID.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_encryption_key_id='$safe_swift_encryption_key_id'";
        }

        // Swift disable encryption
        if(isset($_REQUEST["swift_disable_encryption"])){
            if($_REQUEST["swift_disable_encryption"] == "yes"){
                $safe_swift_disable_encryption = "yes";
            }else{
                $safe_swift_disable_encryption = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_disable_encryption='$safe_swift_disable_encryption'";
        }

        if(isset($_REQUEST["swift_object_replicator_concurrency"])){
            $safe_swift_object_replicator_concurrency = safe_int("swift_object_replicator_concurrency");
            if($safe_swift_object_replicator_concurrency === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: swift_object_replicator_concurrency is not an int.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_object_replicator_concurrency='$safe_swift_object_replicator_concurrency'";
        }

        if(isset($_REQUEST["swift_rsync_connection_limit"])){
            $safe_swift_rsync_connection_limit = safe_int("swift_rsync_connection_limit");
            if($safe_rsync_connection_limit === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: swift_rsync_connection_limit is not an int.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_rsync_connection_limit='$safe_swift_rsync_connection_limit'";
        }

        // Swift swift_public_cloud_middlewares
        if(isset($_REQUEST["swift_public_cloud_middlewares"])){
            if($_REQUEST["swift_public_cloud_middlewares"] == "yes"){
                $safe_swift_public_cloud_middlewares = "yes";
            }else{
                $safe_swift_public_cloud_middlewares = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "swift_public_cloud_middlewares='$safe_swift_public_cloud_middlewares'";
        }

        // External swift stuff
        if(isset($_REQUEST["extswift_use_external"])){
            if($_REQUEST["extswift_use_external"] == "yes"){
                $safe_extswift_use_external = "yes";
            }else{
                $safe_extswift_use_external = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_use_external='$safe_extswift_use_external'";
        }

        if(isset($_REQUEST["extswift_auth_url"])){
            $safe_extswift_auth_url = safe_url("extswift_auth_url");
            if($safe_extswift_auth_url === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: extswift_auth_url is not a valid URL.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_auth_url='$safe_extswift_auth_url'";
        }

        if(isset($_REQUEST["extswift_region"])){
            $safe_extswift_region = safe_password("extswift_region");
            if($safe_extswift_region === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: extswift_region is not a valid fqdn.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_region='$safe_extswift_region'";
        }

        if(isset($_REQUEST["extswift_proxy_url"])){
            $safe_extswift_proxy_url = safe_url("extswift_proxy_url");
            if($safe_extswift_proxy_url === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: extswift_proxy_url is not a valid URL.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_proxy_url='$safe_extswift_proxy_url'";
        }

        if(isset($_REQUEST["extswift_project_name"])){
            $safe_extswift_project_name = safe_fqdn("extswift_project_name");
            if($safe_extswift_project_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid extswift_project_name.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_project_name='$safe_extswift_project_name'";
        }

        if(isset($_REQUEST["extswift_project_domain_name"])){
            $safe_extswift_project_domain_name = safe_fqdn("extswift_project_domain_name");
            if($safe_extswift_project_domain_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid extswift_project_domain_name.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_project_domain_name='$safe_extswift_project_domain_name'";
        }

        if(isset($_REQUEST["extswift_user_name"])){
            $safe_extswift_user_name = safe_fqdn("extswift_user_name");
            if($safe_extswift_user_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid extswift_user_name.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_user_name='$safe_extswift_user_name'";
        }

        if(isset($_REQUEST["extswift_user_domain_name"])){
            $safe_extswift_user_domain_name = safe_fqdn("extswift_user_domain_name");
            if($safe_extswift_user_domain_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid extswift_user_domain_name.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_user_domain_name='$safe_extswift_user_domain_name'";
        }

        if(isset($_REQUEST["extswift_password"])){
            $safe_extswift_password = safe_password("extswift_password");
            if($safe_extswift_password === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid extswift_password.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "extswift_password='$safe_extswift_password'";
        }

        // Time server host
        if(isset($_REQUEST["time_server_host"])){
            foreach(explode(";",$_REQUEST["time_server_host"]) as $this_time_server_host) {
                if(validate_fqdn_str($this_time_server_host) === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not valid time server host. '$this_time_server_host'";
                    return $json;
                }
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "time_server_host='".$_REQUEST["time_server_host"]."'";
        }

        // Name servers
        if(isset($_REQUEST["nameserver_v4_primary"])){
            $safe_nameserver_v4_primary = safe_ipv4("nameserver_v4_primary");
            if($safe_nameserver_v4_primary === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid IP address for a name server.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nameserver_v4_prim='$safe_nameserver_v4_primary'";
        }

        if(isset($_REQUEST["nameserver_v4_secondary"])){
            $safe_nameserver_v4_secondary = safe_ipv4("nameserver_v4_secondary");
            if($safe_nameserver_v4_secondary === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid IP address for a name server.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nameserver_v4_sec='$safe_nameserver_v4_secondary'";
        }

        if(isset($_REQUEST["nameserver_v6_primary"])){
            $safe_nameserver_v6_primary = safe_ipv6("nameserver_v6_primary");
            if($safe_nameserver_v6_primary === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid IP address for a name server.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nameserver_v6_prim='$safe_nameserver_v6_primary'";
        }

        if(isset($_REQUEST["nameserver_v6_secondary"])){
            $safe_nameserver_v6_secondary = safe_ipv6("nameserver_v6_secondary");
            if($safe_nameserver_v6_secondary === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid IP address for a name server.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nameserver_v6_sec='$safe_nameserver_v4_secondary'";
        }

        // VIP hostname (ie: api hostname)
        if(isset($_REQUEST["vip_hostname"])){
            $safe_vip_hostname = safe_fqdn("vip_hostname");
            if($safe_vip_hostname === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid time server host.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "vip_hostname='$safe_vip_hostname'";
        }

        if(isset($_REQUEST["amp_secgroup_list"])){
            $safe_amp_secgroup_list = safe_uuid_list("amp_secgroup_list");
            if($safe_amp_secgroup_list === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid UUID list for amp_secgroup_list.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "amp_secgroup_list='$safe_amp_secgroup_list'";
        }

        if(isset($_REQUEST["amp_boot_network_list"])){
            $safe_amp_boot_network_list = safe_uuid_list("amp_boot_network_list");
            if($safe_amp_boot_network_list === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid UUID list for amp_boot_network_list.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "amp_boot_network_list='$safe_amp_boot_network_list'";
        }

        if(isset($_REQUEST["disable_notifications"])){
            if($_REQUEST["disable_notifications"] == "yes"){
                $safe_disable_notifications = "yes";
            }else{
                $safe_disable_notifications = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "disable_notifications='$safe_disable_notifications'";
        }

        if(isset($_REQUEST["enable_monitoring_graphs"])){
            if($_REQUEST["enable_monitoring_graphs"] == "yes"){
                $safe_enable_monitoring_graphs = "yes";
            }else{
                $safe_enable_monitoring_graphs = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "enable_monitoring_graphs='$safe_enable_monitoring_graphs'";
        }
        if(isset($_REQUEST["statsd_hostname"])){
            $safe_statsd_hostname = safe_fqdn("statsd_hostname");
            if($safe_statsd_hostname == FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid statsd host.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "statsd_hostname='$safe_statsd_hostname'";
        }

        if(isset($_REQUEST["monitoring_graphite_host"])){
            $safe_monitoring_graphite_host = safe_fqdn("monitoring_graphite_host");
            if($safe_monitoring_graphite_host === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid monitoring graphite host.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "monitoring_graphite_host='$safe_monitoring_graphite_host'";
        }

        if(isset($_REQUEST["monitoring_graphite_port"])){
            $safe_monitoring_graphite_port = safe_int("monitoring_graphite_port");
            if($safe_monitoring_graphite_port === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid monitoring graphite port.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "monitoring_graphite_port='$safe_monitoring_graphite_port'";
        }
        if(isset($_REQUEST["self_signed_api_cert"])){
            if($_REQUEST["self_signed_api_cert"] == "yes"){
                $safe_self_signed_api_cert = "yes";
            }else{
                $safe_self_signed_api_cert = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "self_signed_api_cert='$safe_self_signed_api_cert'";
        }

        # Emulated CPU config
        if(isset($_REQUEST["cpu_mode"])){
            $safe_cpu_mode = safe_fqdn("cpu_mode");
            if($safe_cpu_mode === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid cpu-mode.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "cpu_mode='$safe_cpu_mode'";
        }

        if(isset($_REQUEST["cpu_model"])){
            $safe_cpu_model = safe_password("cpu_model");
            if($safe_cpu_model === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid cpu-model.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "cpu_model='$safe_cpu_model'";
        }

        if(isset($_REQUEST["cpu_model_extra_flags"])){
            if($_REQUEST["cpu_model_extra_flags"] == ""){
                $safe_cpu_model_extra_flags = "";
            }else{
                $safe_cpu_model_extra_flags = safe_password("cpu_model_extra_flags");
                if($safe_cpu_model_extra_flags === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not valid cpu_model_extra_flags here.";
                    return $json;
                }
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "cpu_model_extra_flags='$safe_cpu_model_extra_flags'";
        }

        if(isset($_REQUEST["hw_machine_type"])){
            if($_REQUEST["hw_machine_type"] == ""){
                $safe_hw_machine_type = "";
            }else{
                $safe_hw_machine_type = safe_password("hw_machine_type");
                if($safe_hw_machine_type === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not valid hw_machine_type here.";
                    return $json;
                }
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "hw_machine_type='$safe_hw_machine_type'";
        }

        if(isset($_REQUEST["nova_skip_cpu_compare_on_dest"])){
            if($_REQUEST["nova_skip_cpu_compare_on_dest"] == "yes"){
                $safe_nova_skip_cpu_compare_on_dest = "yes";
            }elseif($_REQUEST["nova_skip_cpu_compare_on_dest"] == "no"){
                $safe_nova_skip_cpu_compare_on_dest = "no";
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid nova_skip_cpu_compare_on_dest.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nova_skip_cpu_compare_on_dest='$safe_nova_skip_cpu_compare_on_dest'";
        }

        if(isset($_REQUEST["nova_skip_cpu_compare_at_startup"])){
            if($_REQUEST["nova_skip_cpu_compare_at_startup"] == "yes"){
                $safe_nova_skip_cpu_compare_at_startup = "yes";
            }elseif($_REQUEST["nova_skip_cpu_compare_at_startup"] == "no"){
                $safe_nova_skip_cpu_compare_at_startup = "no";
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid nova_skip_cpu_compare_at_startup.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nova_skip_cpu_compare_at_startup='$safe_nova_skip_cpu_compare_at_startup'";
        }

        if(isset($_REQUEST["nova_skip_hypervisor_version_check_on_lm"])){
            if($_REQUEST["nova_skip_hypervisor_version_check_on_lm"] == "yes"){
                $safe_nova_skip_hypervisor_version_check_on_lm = "yes";
            }elseif($_REQUEST["nova_skip_hypervisor_version_check_on_lm"] == "no"){
                $safe_nova_skip_hypervisor_version_check_on_lm = "no";
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid nova_skip_hypervisor_version_check_on_lm.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "nova_skip_hypervisor_version_check_on_lm='$safe_nova_skip_hypervisor_version_check_on_lm'";
        }

        if(isset($_REQUEST["first_master"])){
            $safe_first_master_serial = safe_serial("first_master");
            if($safe_first_master_serial === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid chassis serial number.";
                return $json;
            }
            $r = mysqli_query($con, "SELECT * FROM machines WHERE serial='$safe_first_master_serial' AND role='controller' AND cluster='".$cluster["id"]."'");
            if($r === FALSE){
                $json["status"] = "error";
                $json["message"] = mysqli_error($con). " doing $q";
                return $json;
            }
            $n = mysqli_num_rows($r);
            if($n != 1){
                $json["status"] = "error";
                $json["message"] = "Error: machine with serial $safe_machine_serial doesn't exist as a controller on cluster $safe_cluster_name.";
                return $json;
            }
            $machine = mysqli_fetch_array($r);
            $machine_id      = $machine["id"];
            if($update != ""){
                $update .= ", ";
            }
            $update .= "first_master_machine_id='$machine_id'";
        }

        // initial_cluster_setup
        if(isset($_REQUEST["cephosd_automatic_provisionning"])){
            if($_REQUEST["cephosd_automatic_provisionning"] == "yes"){
                $safe_cephosd_automatic_provisionning = "yes";
            }else{
                $safe_cephosd_automatic_provisionning = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "cephosd_automatic_provisionning='$safe_cephosd_automatic_provisionning'";
        }

        if(isset($_REQUEST["haproxy_custom_url"])){
            $safe_haproxy_custom_url = safe_url("haproxy_custom_url");
            if($safe_haproxy_custom_url === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: haproxy_custom_url is not a valid URL.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "haproxy_custom_url='$safe_haproxy_custom_url'";
        }

        # Build the API using the variables.json file
        $json_file = file_get_contents("/usr/share/openstack-cluster-installer/variables.json");
        $dec_json = json_decode($json_file, TRUE);
        $items_json_array = $dec_json["clusters"];
        $a_keys = array_keys($items_json_array);
        $n = sizeof($a_keys);
        for($i=0;$i<$n;$i++){
                $col = $a_keys[$i];
                $attr = $items_json_array[$col];
                if(isset($_REQUEST[$col])){
                    switch($attr["type"]){
                    case "int":
                        $safe_value = safe_int($col);
                        break;
                    case "float":
                        $safe_value = safe_float($col);
                        break;
                    case "boolean":
                        if($_REQUEST[$col] == "yes"){
                            $safe_value = "yes";
                        }else{
                            $safe_value = "no";
                        }
                        break;
                    case "fqdn":
                        $safe_value = safe_fqdn($col);
                        break;
                    case "string":
                        $safe_value = safe_password($col);
                        break;
                    case "ip_list":
                        $safe_value = safe_ip_list($col);
                        break;
                    default:
                        $safe_value = FALSE;
                        break;
                    }
                    if($safe_value === FALSE){
                        $json["status"] = "error";
                        $json["message"] = "Error: not valid $col here.";
                        return $json;
                    }
                    if($update != ""){
                        $update .= ", ";
                    }
                    $update .= "$col='$safe_value'";
                }
        }

        $q = "UPDATE clusters SET $update WHERE name='$safe_cluster_name'";
        if($update != ""){
            $r = mysqli_query($con, $q);
        }

        return $json;
        break;
    case "cluster_show_ips":
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster not found.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $cluster_id = $cluster["id"];
        $q = "SELECT machines.hostname AS hostname, INET_NTOA(ips.ip) AS ipaddr FROM machines,ips WHERE machines.cluster='$cluster_id' AND machines.id=ips.machine";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $json["data"][] = mysqli_fetch_array($r);
        }
        return $json;
        break;
    case "machine_ipmi_adopt":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        machine_ipmi_adopt($con, $conf, $machine);
        return $json;
        break;
    case "machine_destroy":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $machine_id = $machine["id"];

        machine_delete_from_monitoring($con, $conf, $machine);
        machine_delete_host_dns($con, $conf, $machine, 'yes');

        $json = machine_destroy($con, $conf, $machine_id);

        return $json;
        break;
    case "get_machine_status":
        # Validate IPv4
        $safe_ip = safe_ipv4("ipaddr");
        if($safe_ip === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: wrong ipaddr param.";
            return $json;
        }
        if(check_machine_with_ip_exists($safe_ip) === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: machine with ip $safe_ip doesn't exist.";
            return $json;
        }
        # Fetch machine info and output
        $r = mysqli_query($con, "SELECT * FROM machines WHERE ipaddr='$safe_ip'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $install_machine = mysqli_fetch_array($r);
        $json["data"] = $install_machine;
        return $json;
        break;
    case "password_list":
        $r = mysqli_query($con, "SELECT * FROM passwords");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        $json["data"] = array();
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;
    case "password_show":
        $safe_id = safe_int("id");
        if($safe_id === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: id is not an int.";
            return $json;
        }
        $r = mysqli_query($con, "SELECT * FROM passwords WHERE id='$safe_id'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Could not find password with id: $safe_id.";
        }
        $json["data"] = array();
        $a = mysqli_fetch_array($r);
        if( $a["passtype"] == "ssh" ){
            $a["passtxt1"] = unserialize($a["passtxt1"]);
            $a["passtxt2"] = unserialize($a["passtxt2"]);
        }
        $json["data"] = $a;

        return $json;
        break;
    case "password_set":
        $safe_id = safe_int("id");
        if($safe_id === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: id is not an int.";
            return $json;
        }
        $r = mysqli_query($con, "SELECT * FROM passwords WHERE id='$safe_id'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Could not find password with id: $safe_id.";
        }
        $a = mysqli_fetch_array($r);
        switch($a["passtype"]){
        case "db":
        case "credential1":
        case "credential2":
        case "openstackkey":
        case "stats":
            $safe_pass = mysqli_real_escape_string($con, $_REQUEST['pass']);
            $q = "UPDATE passwords SET pass='$safe_pass' WHERE id='$safe_id'";
            break;
        case "fsid":
        case "libvirtuuid":
        case "uuid":
            $safe_uuid = safe_uuid('pass');
            if($safe_uuid === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: pass does not look like an UUID.";
                return $json;
            }
            $q = "UPDATE passwords SET pass='$safe_uuid' WHERE id='$safe_id'";
            break;
        case "ssh":
            $safe_pubkey = mysqli_real_escape_string($con, $_REQUEST['passtxt1']);
            if(! isset($_REQUEST["passtxt2"]) || $_REQUEST["passtxt2"] == ""){
                $safe_privkey = "";
            }else{
                $safe_privkey = safe_password('passtxt2');
                if($safe_id === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: private key format error.";
                    return $json;
                }
            }
            $q = "UPDATE passwords SET passtxt1='" .serialize($safe_pubkey). "', passtxt2='" . serialize($safe_privkey). "' WHERE id='$safe_id'";
            break;
        default:
            $json["status"] = "error";
            $json["message"] = "Error: password type not handled line: ".__LINE__." file: ".__FILE__;
            return $json;
            break;
        }
        $r = mysqli_query($con, $q);
        return $json;
        break;
    case "machine_list":
        $r = mysqli_query($con, "SELECT * FROM machines");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        $json["data"] = array();
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
            $allfld = array("hostname","dell_lifecycle_version","notes","loc_dc","loc_row","loc_rack","loc_u_start","loc_u_end","ladvd_report","ipmi_addr","ipmi_detected_ip","ipmi_port","ipmi_username","ipmi_password");
            foreach ($allfld as &$fld){
                if($json["data"][$i][$fld] == ""){
                    $json["data"][$i][$fld] = "-";
                }
            }
            # For each machines, get the location_name and swiftregion
            if($a["location_id"] == NULL){
                $json["data"][$i]["location_name"] = "-";
                $json["data"][$i]["swiftregion_name"] = "-";
            }else{
                $rl = mysqli_query($con, "SELECT name,swiftregion FROM locations WHERE id='".$a["location_id"]."'");
                $nl = mysqli_num_rows($rl);
                if($nl == 0){
                    $json["data"][$i]["location_name"] = "-";
                    $json["data"][$i]["swiftregion_name"] = "-";
                }else{
                    $al = mysqli_fetch_array($rl);
                    $json["data"][$i]["location_name"] = $al["name"];
                    $json["data"][$i]["swiftregion_name"] = $al["swiftregion"];
                }
            }
            # For each machines, get the block devices
            $bd_r = mysqli_query($con, "SELECT name,size_mb FROM blockdevices WHERE machine_id='".$a["id"]."' ORDER BY LENGTH(name),name");
            $bd_n = mysqli_num_rows($bd_r);
            if($bd_n == 0){
                $json["data"][$i]["blockdevices"] = "-";
            }else{
                $json["data"][$i]["blockdevices"] = "";
                for($j=0;$j<$bd_n;$j++){
                    $bd_a = mysqli_fetch_array($bd_r);
                    if($json["data"][$i]["blockdevices"] != ""){
                        $json["data"][$i]["blockdevices"] .= "/";
                    }
                    if($bd_a["size_mb"] >= 2097152){
                        $block_size = round($bd_a["size_mb"] / 1048576) . "TB";
                    }elseif($bd_a["size_mb"] >= 2048){
                        $block_size = round($bd_a["size_mb"] / 1024) . "GB";
                    }else{
                        $block_size = $bd_a["size_mb"] . "MB";
                    }
                    $json["data"][$i]["blockdevices"] .= $bd_a["name"] . ":" . $block_size;
                }
            }

            # For each machines, get the network devices
            $nd_r = mysqli_query($con, "SELECT name,macaddr,max_speed,switchport_name,switch_hostname FROM ifnames WHERE machine_id='".$a["id"]."' ORDER BY name");
            $nd_n = mysqli_num_rows($nd_r);
            if($nd_n == 0){
                $json["data"][$i]["nics"] = "-";
                $json["data"][$i]["links"] = "-";
            }else{
                $json["data"][$i]["nics"] = "";
                $json["data"][$i]["links"] = "";
                for($j=0;$j<$nd_n;$j++){
                    $nd_a = mysqli_fetch_array($nd_r);
                    if($json["data"][$i]["nics"] != ""){
                        $json["data"][$i]["nics"] .= "/";
                    }
                    if($json["data"][$i]["links"] != ""){
                        $json["data"][$i]["links"] .= "/";
                    }
                    $speed = $nd_a["max_speed"];
                    if($speed < 1000){
                        $speed = $speed . "MBits";
                    }else{
                        $speed = ($speed / 1000) . "GBits";
                    }
                    $json["data"][$i]["nics"] .= $nd_a["name"] . "_" . $nd_a["macaddr"] . "@" . $speed . "_" . $nd_a["switch_hostname"] . "_" . $nd_a["switchport_name"];
                    $json["data"][$i]["links"] .= $nd_a["name"] . "_" . $nd_a["switch_hostname"] . "_" . $nd_a["switchport_name"];
                }
            }

            # For each machines, get the cluster name
            if($a["cluster"] == NULL){
                $json["data"][$i]["cluster_name"] = "-";
            }else{
                $rc = mysqli_query($con, "SELECT name FROM clusters WHERE id='".$a["cluster"]."'");
                $nc = mysqli_num_rows($rc);
                if($nc == 0){
                    $json["data"][$i]["cluster_name"] = "-";
                }else{
                    $ac = mysqli_fetch_array($rc);
                    $json["data"][$i]["cluster_name"] = $ac["name"];
                }
            }
            # For each machines, get the provisionned IPs
            if($a["cluster"] == NULL){
                $json["data"][$i]["mgmt_ip"] = "-";
            }else{
                $json["data"][$i]["mgmt_ip"] = "";
                $rnet = mysqli_query($con, "SELECT INET_NTOA(ips.ip) AS ipaddr, networks.name AS networkname FROM ips,networks WHERE ips.network=networks.id AND machine='".$a["id"]."' AND usefor='machine' AND networks.role NOT LIKE 'ipmi' AND networks.role NOT LIKE 'vm-net' AND networks.role NOT LIKE 'ceph-cluster' AND networks.role NOT LIKE 'ovs-bridge' AND networks.role NOT LIKE 'vip'");
                $nnet = mysqli_num_rows($rnet);
                for($j=0;$j<$nnet;$j++){
                    $anet = mysqli_fetch_array($rnet);
                    if($json["data"][$i]["mgmt_ip"] != ""){
                        $json["data"][$i]["mgmt_ip"] .= "/";
                    }
                    $json["data"][$i]["mgmt_ip"] .= $anet["ipaddr"] . "@" . $anet["networkname"];
                }
            }
        }
        return $json;
        break;
    case "machine_guessed_profile":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        if(isset($_REQUEST["debug"]) && $_REQUEST["debug"] = "yes"){
            $debug="yes";
        }else{
            $debug="no";
        }

        $json = hardware_profile_guess_profile($con, $conf, $machine["id"],$debug);

        return $json;
        break;
    case "machine_check_megacli_applied":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        if(isset($_REQUEST["profile_name"]) && $_REQUEST["profile_name"] != ""){
            $safe_profile_name = safe_fqdn("profile_name");
            if($safe_profile_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid profile name.";
                return $json;
            }
        }

        $json = hardware_profile_check_megacli_applied($con, $conf, $machine["id"], $safe_profile_name);

        return $json;
        break;
    case "profile_list":
        $json = hardware_profile_list($con, $conf);
        return $json;
        break;
    case "machine_megacli_apply":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        if(isset($_REQUEST["profile_name"]) && $_REQUEST["profile_name"] != ""){
            $safe_profile_name = safe_fqdn("profile_name");
            if($safe_profile_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid profile name.";
                return $json;
            }
        }else{
            $safe_profile_name = "";
        }

        if(isset($_REQUEST["debug"]) && $_REQUEST["debug"] == "yes"){
            $debug="yes";
        }else{
            $debug="no";
        }

        $json = hardware_profile_apply_megacli_raid($con, $conf, $machine["id"], $safe_profile_name,$debug);

        return $json;
        break;
    case "machine_megacli_reset_raid":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        $json = hardware_profile_apply_megacli_reset_raid($con, $conf, $machine["id"]);

        return $json;
        break;
    case "machine_guess_racking":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $ret = auto_racking_guess_location($con, $conf, $machine["id"]);
        if($ret["status"] != "success"){
            return $ret;
        }

        if(!isset($ret["data"]) || sizeof($ret["data"]) == 0){
            $json["data"] = "No racking info could be guessed.";
        }else{
            $json["data"] = "Machine is in datacenter ".$ret["data"]["dc"]." row ".$ret["data"]["row"]." rack ".$ret["data"]["rack"]." ustart ".$ret["data"]["u_start"]." uend ".$ret["data"]["u_end"].".";
        }

        return $json;
        break;
    case "machine_auto_rack":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $ret = auto_racking_auto_assign_location($con, $conf, $machine["id"]);
        if($ret["status"] != "success"){
            return $ret;
        }

        return $json;
        break;
    case "machine_auto_add":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $json = auto_provision_add_machine($con, $conf, $machine["id"]);

        return $json;
        break;
    case "machine_to_dns":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $json = machine_create_host_dns($con, $conf, $machine, 'yes');

        return $json;
        break;
    case "machine_out_of_dns":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $json = machine_delete_host_dns($con, $conf, $machine, 'yes');

        return $json;
        break;
    case "machine_to_monitoring":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $json = machine_add_to_monitoring($con, $conf, $machine, 'yes');

        return $json;
        break;
    case "machine_out_of_monitoring":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $json = machine_delete_from_monitoring($con, $conf, $machine);

        return $json;
        break;
    case "machine_gen_root_pass":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        machine_gen_root_pass($con, $conf, $machine, 'yes');

        return $json;
        break;
    case "machine_forget_root_pass":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        machine_forget_root_pass($con, $conf, $machine, 'yes');

        return $json;
        break;
    case "machine_save_ipmi_pass":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        if(machine_save_ipmi_pass($con, $conf, $machine) === FALSE){
            $json["status"] = "error";
            $json["message"] = "Could not save IPMI password.";
            return $json;
        }

        return $json;
        break;
    case "machine_forget_ipmi_pass":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        if(machine_forget_ipmi_pass($con, $conf, $machine) === FALSE){
            $json["status"] = "error";
            $json["message"] = "Could not delete IPMI password.";
            return $json;
        }

        return $json;
        break;
    case "machine_report_counter_reset":
        $ret = get_machine_from_serial_or_hostname($con, $conf);
        if($ret["status"] != "success"){ return $ret; }
        $machine = $ret["data"];

        $q = "UPDATE machines SET report_counter='0' WHERE id='".$machine["id"]."'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }

        return $json;
        break;
    case "machine_blk":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $json["data"] = Array();

        $q = "SELECT * FROM blockdevices WHERE machine_id='".$machine["id"]."'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        $blks = [];
        for($i=0;$i<$n;$i++){
            $blks[] = mysqli_fetch_array($r);
        }
        $json["data"]["blks"] = $blks;

        return $json;
        break;
    case "machine_show":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        $r = mysqli_query($con, "SELECT * FROM clusters WHERE id='".$machine["cluster"]."'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $json["data"]["machine_cluster"] = $cluster;

        $r = mysqli_query($con, "SELECT * FROM blockdevices WHERE machine_id='".$machine["id"]."' ORDER BY LENGTH(name),name");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        $blockdevs = [];
        for($i=0;$i<$n;$i++){
            $blockdevs[] = mysqli_fetch_array($r);
        }
        $json["data"]["machine_blockdevices"] = $blockdevs;

        $r = mysqli_query($con, "SELECT INET_NTOA(ips.ip) as ipaddr,networks.name AS networkname FROM ips,networks WHERE machine='".$machine["id"]."' AND ips.network=networks.id");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        $ips = [];
        for($i=0;$i<$n;$i++){
            $ips[] = mysqli_fetch_array($r);
        }
        $json["data"]["machine_ips"] = $ips;

        # All ifaces
        $r = mysqli_query($con, "SELECT * FROM ifnames WHERE machine_id='".$machine["id"]."' ORDER BY name");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        $ifs = [];
        for($i=0;$i<$n;$i++){
            $ifs[] = mysqli_fetch_array($r);
        }
        $json["data"]["machine_ifs"] = $ifs;

        # All megacli devices
        $r = mysqli_query($con, "SELECT * FROM physblockdevices WHERE machine_id='".$machine["id"]."' ORDER BY slot");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $physbd = [];
            for($i=0;$i<$n;$i++){
                $physbd[] = mysqli_fetch_array($r);
            }
            $json["data"]["machine_phys_blockdevices"] = $physbd;
        }

        # All block device controllers
        $r = mysqli_query($con, "SELECT * FROM blkdev_ctrl WHERE machine_id='".$machine["id"]."'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $blkdev_ctrl = [];
            for($i=0;$i<$n;$i++){
                $blkdev_ctrl[] = mysqli_fetch_array($r);
            }
            $json["data"]["blkdev_ctrl"] = $blkdev_ctrl;
        }

        return $json;
        break;
    case "machine_set":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $Q_ADDON = "";

        if(isset($_REQUEST["use_ceph"])){
            if($_REQUEST["use_ceph"] == "yes"){
                $Q_ADDON .= "use_ceph_if_available='yes'";
            }else{
                $Q_ADDON .= "use_ceph_if_available='no'";
            }
        }

        if(isset($_REQUEST["ceph_az"])){
            $ceph_az = safe_int("ceph_az");
            if($ceph_az === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid AZ number for ceph_az.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ceph_az='$ceph_az'";
        }


        if(isset($_REQUEST["dest_blk"])){
            $dest_blk = safe_blockdev_name("dest_blk");
            if($dest_blk === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid raid device name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "dest_blk='$dest_blk'";
        }

        if(isset($_REQUEST["install_on_raid"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["install_on_raid"] == "yes"){
                $Q_ADDON .= "install_on_raid='yes'";
            }else{
                $Q_ADDON .= "install_on_raid='no'";
            }
        }

        if(isset($_REQUEST["ceph_osd_initial_setup"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["ceph_osd_initial_setup"] == "yes"){
                $Q_ADDON .= "ceph_osd_initial_setup='yes'";
            }else{
                $Q_ADDON .= "ceph_osd_initial_setup='no'";
            }
        }

        if(isset($_REQUEST["force_no_bgp2host"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["force_no_bgp2host"] == "yes"){
                $Q_ADDON .= "force_no_bgp2host='yes'";
            }else{
                $Q_ADDON .= "force_no_bgp2host='no'";
            }
        }

        if(isset($_REQUEST["force_frr"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["force_frr"] == "yes"){
                $Q_ADDON .= "force_frr='yes'";
            }else{
                $Q_ADDON .= "force_frr='no'";
            }
        }

        if(isset($_REQUEST["force_frr_nic1"])){
            $force_frr_nic1 = safe_ethname("force_frr_nic1");
            if($force_frr_nic1 === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid NIC value for force_frr_nic1.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "force_frr_nic1='$force_frr_nic1'";
        }

        if(isset($_REQUEST["force_frr_nic2"])){
            $force_frr_nic2 = safe_ethname("force_frr_nic2");
            if($force_frr_nic2 === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid NIC value for force_frr_nic2.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "force_frr_nic2='$force_frr_nic2'";
        }

        if(isset($_REQUEST["force_frr_vlan"])){
            $force_frr_vlan = safe_int("force_frr_vlan");
            if($force_frr_vlan === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid VLAN value for force_frr_vlan.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "force_frr_vlan='$force_frr_vlan'";
        }

        if(isset($_REQUEST["raid_type"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            switch($_REQUEST["raid_type"]){
            case "0":
                $Q_ADDON .= "raid_type='0'";
                break;
            default:
            case "1":
                $Q_ADDON .= "raid_type='1'";
                break;
            case "5":
                $Q_ADDON .= "raid_type='5'";
                break;
            case "10":
                $Q_ADDON .= "raid_type='10'";
                break;
            }
        }

        if(isset($_REQUEST["raid_dev0"])){
            $raid_dev0 = safe_blockdev_name("raid_dev0");
            if($raid_dev0 === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid raid device name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "raid_dev0='$raid_dev0'";
        }

        if(isset($_REQUEST["raid_dev1"])){
            $raid_dev1 = safe_blockdev_name("raid_dev1");
            if($raid_dev1 === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid raid device name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "raid_dev1='$raid_dev1'";
        }

        if(isset($_REQUEST["raid_dev2"])){
            $raid_dev2 = safe_blockdev_name("raid_dev2");
            if($raid_dev2 === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid raid device name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "raid_dev2='$raid_dev2'";
        }

        if(isset($_REQUEST["raid_dev3"])){
            $raid_dev3 = safe_blockdev_name("raid_dev3");
            if($raid_dev3 === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid raid device name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "raid_dev3='$raid_dev3'";
        }

        if(isset($_REQUEST["serial_console_device"])){
            $serial_console_device = safe_blockdev_name("serial_console_device");
            if($serial_console_device === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid serial device name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "serial_console_dev='$serial_console_device'";
        }

        $location_param_list = [ "loc_dc", "loc_row", "loc_rack", "loc_u_start", "loc_u_end" ];
        foreach ($location_param_list as &$one_param){
            if(isset($_REQUEST[$one_param])){
                $safe_param_value = safe_fqdn($one_param);
                if($safe_param_value === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not valid $one_param parameter.";
                    return $json;
                }
                if($Q_ADDON != ""){
                    $Q_ADDON .= ", ";
                }
                $Q_ADDON .= "$one_param='$safe_param_value'";
            }
        }

        if(isset($_REQUEST["use_gpu"])){
            if($_REQUEST["use_gpu"] == "yes"){
                $safe_use_gpu = "yes";
            }else{
                $safe_use_gpu = "no";
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "use_gpu='$safe_use_gpu'";
        }

        if(isset($_REQUEST["nested_virt"])){
            if($_REQUEST["nested_virt"] == "yes"){
                $safe_nested_virt = "yes";
            }elseif($_REQUEST["nested_virt"] == "cluster_value"){
                $safe_nested_virt = "cluster_value";
            }else{
                $safe_nested_virt = "no";
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "nested_virt='$safe_nested_virt'";
        }

        if(isset($_REQUEST["gpu_name"])){
            $safe_gpu_name = safe_password('gpu_name');
            if($safe_gpu_name === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid GPU name.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "gpu_name='$safe_gpu_name'";
        }

        if(isset($_REQUEST["gpu_vendor_id"])){
            $safe_gpu_vendor_id = safe_password('gpu_vendor_id');
            if($safe_gpu_vendor_id === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid GPU vendor id.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "gpu_vendor_id='$safe_gpu_vendor_id'";
        }

        if(isset($_REQUEST["gpu_product_id"])){
            $safe_gpu_product_id = safe_password('gpu_product_id');
            if($safe_gpu_product_id === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid GPU product id.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "gpu_product_id='$safe_gpu_product_id'";
        }

        if(isset($_REQUEST["gpu_device_type"])){
            if($_REQUEST["gpu_device_type"] != "type-PCI" AND $_REQUEST["gpu_device_type"] != "type-PF" AND $_REQUEST["gpu_device_type"] != "type-VF"){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid GPU product id.";
                return $json;
            }else{
                $safe_gpu_device_type = $_REQUEST["gpu_device_type"];
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "gpu_device_type='$safe_gpu_device_type'";
        }

        if(isset($_REQUEST["vfio_ids"])){
            $safe_vfio_ids = safe_password('vfio_ids');
            if($safe_vfio_ids === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid GPU product id.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "vfio_ids='$safe_vfio_ids'";
        }

        if(isset($_REQUEST["cpu_mode"])){
            if($_REQUEST["cpu_mode"] == "host-model" || $_REQUEST["cpu_mode"] == "host-passthrough" || $_REQUEST["cpu_mode"] == "custom" || $_REQUEST["cpu_mode"] == "cluster_value"){
                $safe_cpu_mode = $_REQUEST["cpu_mode"];
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid cpu-mode.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "cpu_mode='$safe_cpu_mode'";
        }

        if(isset($_REQUEST["cpu_model"])){
            $safe_cpu_model = safe_password('cpu_model');
            if($safe_cpu_model === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid cpu-model.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "cpu_model='$safe_cpu_model'";
        }

        if(isset($_REQUEST["cpu_model_extra_flags"])){
            if($_REQUEST["cpu_model_extra_flags"] == ""){
                $safe_cpu_model_extra_flags = "";
            }else{
                $safe_cpu_model_extra_flags = safe_password('cpu_model_extra_flags');
                if($safe_cpu_model_extra_flags === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not a valid cpu_model_extra_flags.";
                    return $json;
                }
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "cpu_model_extra_flags='$safe_cpu_model_extra_flags'";
        }

        if(isset($_REQUEST["hw_machine_type"])){
            if($_REQUEST["hw_machine_type"] == ""){
                $safe_hw_machine_type = "";
            }else{
                $safe_hw_machine_type = safe_password('hw_machine_type');
                if($safe_hw_machine_type === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not a valid hw_machine_type.";
                    return $json;
                }
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "hw_machine_type='$safe_hw_machine_type'";
        }

        if(isset($_REQUEST["nova_skip_cpu_compare_on_dest"])){
            if($_REQUEST["nova_skip_cpu_compare_on_dest"] == "cluster_value"){
                $safe_nova_skip_cpu_compare_on_dest = "cluster_value";
            }elseif($_REQUEST["nova_skip_cpu_compare_on_dest"] == "yes"){
                $safe_nova_skip_cpu_compare_on_dest = "yes";
            }elseif($_REQUEST["nova_skip_cpu_compare_on_dest"] == "no"){
                $safe_nova_skip_cpu_compare_on_dest = "no";
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid nova_skip_cpu_compare_on_dest.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "nova_skip_cpu_compare_on_dest='$safe_nova_skip_cpu_compare_on_dest'";
        }

        if(isset($_REQUEST["nova_skip_cpu_compare_at_startup"])){
            if($_REQUEST["nova_skip_cpu_compare_at_startup"] == "cluster_value"){
                $safe_nova_skip_cpu_compare_at_startup = "cluster_value";
            }elseif($_REQUEST["nova_skip_cpu_compare_at_startup"] == "yes"){
                $safe_nova_skip_cpu_compare_at_startup = "yes";
            }elseif($_REQUEST["nova_skip_cpu_compare_at_startup"] == "no"){
                $safe_nova_skip_cpu_compare_at_startup = "no";
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid nova_skip_cpu_compare_at_startup.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "nova_skip_cpu_compare_at_startup='$safe_nova_skip_cpu_compare_at_startup'";
        }

        if(isset($_REQUEST["nova_skip_hypervisor_version_check_on_lm"])){
            if($_REQUEST["nova_skip_hypervisor_version_check_on_lm"] == "cluster_value"){
                $safe_nova_skip_hypervisor_version_check_on_lm = "cluster_value";
            }elseif($_REQUEST["nova_skip_hypervisor_version_check_on_lm"] == "yes"){
                $safe_nova_skip_hypervisor_version_check_on_lm = "yes";
            }elseif($_REQUEST["nova_skip_hypervisor_version_check_on_lm"] == "no"){
                $safe_nova_skip_hypervisor_version_check_on_lm = "no";
            }else{
                $json["status"] = "error";
                $json["message"] = "Error: not a valid nova_skip_hypervisor_version_check_on_lm.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "nova_skip_hypervisor_version_check_on_lm='$safe_nova_skip_hypervisor_version_check_on_lm'";
        }

        if(isset($_REQUEST["force_dhcp_agent"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["force_dhcp_agent"] == "yes"){
                $Q_ADDON .= "force_dhcp_agent='yes'";
            }else{
                $Q_ADDON .= "force_dhcp_agent='no'";
            }
        }

        if(isset($_REQUEST["swift_store_account"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["swift_store_account"] == "yes"){
                $Q_ADDON .= "swift_store_account='yes'";
            }else{
                $Q_ADDON .= "swift_store_account='no'";
            }
        }
        if(isset($_REQUEST["swift_store_container"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["swift_store_container"] == "yes"){
                $Q_ADDON .= "swift_store_container='yes'";
            }else{
                $Q_ADDON .= "swift_store_container='no'";
            }
        }

        if(isset($_REQUEST["swift_store_object"])){
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            if($_REQUEST["swift_store_object"] == "yes"){
                $Q_ADDON .= "swift_store_object='yes'";
            }else{
                $Q_ADDON .= "swift_store_object='no'";
            }
        }

        if(isset($_REQUEST["hostname"])){
            $safe_hostname = safe_fqdn('hostname');
            if($safe_hostname === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid hostname.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "hostname='$safe_hostname'";
        }

        if(isset($_REQUEST["notes"])){
            $safe_notes = safe_password('notes');
            if($safe_notes === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid note.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "notes='$safe_notes'";
        }

        if(isset($_REQUEST["use_ipmi"])){
            if($_REQUEST["use_ipmi"] == "yes"){
                $safe_use_ipmi = "yes";
            }else{
                $safe_use_ipmi = "no";
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "use_ipmi='$safe_use_ipmi'";
        }

        if(isset($_REQUEST["ipmi_call_chassis_bootdev"])){
            if($_REQUEST["ipmi_call_chassis_bootdev"] == "yes"){
                $safe_ipmi_call_chassis_bootdev = "yes";
            }else{
                $safe_ipmi_call_chassis_bootdev = "no";
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_call_chassis_bootdev='$safe_ipmi_call_chassis_bootdev'";
        }

        if(isset($_REQUEST["ipmi_username"])){
            $safe_ipmi_username = safe_password('ipmi_username');
            if($safe_ipmi_username === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid ipmi_username.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_username='$safe_ipmi_username'";
        }

        if(isset($_REQUEST["ipmi_password"])){
            $safe_ipmi_password = safe_password('ipmi_password');
            if($safe_ipmi_password === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid ipmi_password.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_password='$safe_ipmi_password'";
        }

        if(isset($_REQUEST["ipmi_addr"])){
            $safe_ipmi_addr = safe_ipv4('ipmi_addr');
            if($safe_ipmi_addr === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid ipmi_addr.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_addr='$safe_ipmi_addr'";
        }

        if(isset($_REQUEST["ipmi_port"])){
            $safe_ipmi_port = safe_int('ipmi_port');
            if($safe_ipmi_port === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid ipmi_port.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_port='$safe_ipmi_port'";
        }

        if(isset($_REQUEST["ipmi_netmask"])){
            $safe_ipmi_netmask = safe_ipv4('ipmi_netmask');
            if($safe_ipmi_netmask === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid ipmi_netmask.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_netmask='$safe_ipmi_netmask'";
        }

        if(isset($_REQUEST["ipmi_default_gw"])){
            $safe_ipmi_default_gw = safe_ipv4('ipmi_default_gw');
            if($safe_ipmi_default_gw === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not a valid ipmi_default_gw.";
                return $json;
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_default_gw='$safe_ipmi_default_gw'";
        }

        if(isset($_REQUEST["ipmi_vlan"])){
            if($_REQUEST["ipmi_vlan"] == "off"){
                $safe_ipmi_vlan = "off";
            }else{
                $safe_ipmi_vlan = safe_int('ipmi_vlan');
                if($safe_ipmi_vlan === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Error: not a valid ipmi_vlan.";
                    return $json;
                }
            }
            if($Q_ADDON != ""){
                $Q_ADDON .= ", ";
            }
            $Q_ADDON .= "ipmi_vlan='$safe_ipmi_vlan'";
        }

        # Build the API using the variables.json file
        $json_file = file_get_contents("/usr/share/openstack-cluster-installer/variables.json");
        $dec_json = json_decode($json_file, TRUE);
        $items_json_array = $dec_json["machines"];
        $a_keys = array_keys($items_json_array);
        $n = sizeof($a_keys);
        for($i=0;$i<$n;$i++){
                $col = $a_keys[$i];
                $attr = $items_json_array[$col];
                if(isset($_REQUEST[$col])){
                    switch($attr["type"]){
                    case "int":
                        $safe_value = safe_int($col);
                        break;
                    case "float":
                        $safe_value = safe_float($col);
                        break;
                    case "boolean":
                        if($_REQUEST[$col] == "yes"){
                            $safe_value = "yes";
                        }else{
                            $safe_value = "no";
                        }
                        break;
                    case "fqdn":
                        $safe_value = safe_fqdn($col);
                        break;
                    case "string":
                        $safe_value = safe_password($col);
                        break;
                    default:
                        $safe_value = FALSE;
                        break;
                    }
                    if($safe_value === FALSE){
                        $json["status"] = "error";
                        $json["message"] = "Error: not valid $col here.";
                        return $json;
                    }
                    if($Q_ADDON != ""){
                        $Q_ADDON .= ", ";
                    }
                    $Q_ADDON .= "$col='$safe_value'";
                }
        }


        $q = "UPDATE machines SET $Q_ADDON WHERE serial='$safe_machine_serial'";
        $r = mysqli_query($con, $q);

        return $json;
        break;
    # Remove a machine from a cluster
    case "machine_remove":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $machine_status  = $machine["status"];
        $machine_id      = $machine["id"];
        $machine_cluster = $machine["cluster"];
        $machine_role    = $machine["role"];

        $q = "UPDATE machines SET cluster=NULL, hostname='', role='' WHERE id='$machine_id'";
        $r = mysqli_query($con, $q);

        // If role is controller, check if there's another controller left. If there's at least one, then
        // we must set any of these controllers as first master
        if($machine_role == "controller"){
            $q = "SELECT first_master_machine_id FROM clusters WHERE id='$machine_cluster'";
            $r = mysqli_query($con, $q);
            $cluster = mysqli_fetch_array($r);
            $fm_id = $cluster["first_master_machine_id"];;
            if($fm_id == $machine_id){
                $q = "SELECT * FROM machines WHERE cluster='$machine_cluster' AND role='controller' LIMIT 1;";
                $r = mysqli_query($con, $q);
                $n = mysqli_num_rows($r);
                // No controler left: we set the first_master as NULL
                if($n == 0){
                    $q = "UPDATE clusters SET first_master_machine_id=NULL WHERE id='$machine_cluster'";
                    $r = mysqli_query($con, $q);
                // We just set the first controler we find left as first_master
                }else{
                    $first_master = mysqli_fetch_array($r);
                    $new_fm_id = $first_master["id"];
                    $q = "UPDATE clusters SET first_master_machine_id='$new_fm_id' WHERE id='$machine_cluster'";
                    $r = mysqli_query($con, $q);
                }
            }
        }

        // If role is sql, check if there's another sql node left. If there's at least one, then
        // we must set a sql node as first master
        if($machine_role == "sql"){
            $q = "SELECT first_sql_machine_id FROM clusters WHERE id='$machine_cluster'";
            $r = mysqli_query($con, $q);
            $cluster = mysqli_fetch_array($r);
            $fsql_id = $cluster["first_master_machine_id"];;
            if($fsql_id == $machine_id){
                $q = "SELECT * FROM machines WHERE cluster='$machine_cluster' AND role='sql' LIMIT 1;";
                $r = mysqli_query($con, $q);
                $n = mysqli_num_rows($r);
                // No sql node left: we set the first_master as NULL
                if($n == 0){
                    $q = "UPDATE clusters SET first_sql_machine_id=NULL WHERE id='$machine_cluster'";
                    $r = mysqli_query($con, $q);
                // We just set the first sql node we find left as first_sql
                }else{
                    $first_master = mysqli_fetch_array($r);
                    $new_fsql_id = $first_master["id"];
                    $q = "UPDATE clusters SET first_sql_machine_id='$new_fsql_id' WHERE id='$machine_cluster'";
                    $r = mysqli_query($con, $q);
                }
            }
        }

        // Delete all IPs of the machine in the DB
        $q = "DELETE FROM ips WHERE machine='$machine_id' AND usefor NOT LIKE 'ipmi'";
        $r = mysqli_query($con, $q);
        return $json;
        break;
    # Add a machine to a cluster
    case "machine_add":
        // Check if we have a fixed_ip param
        if(isset($_REQUEST["fixed_ip"]) && $_REQUEST["fixed_ip"] != ""){
            $safe_machine_fixed_ip = safe_ipv4("fixed_ip");
            if($safe_machine_fixed_ip === FALSE){
                $json["status"] = "error";
                $json["message"] = "Error: not valid IPv4 address.";
                return $json;
            }
        }else{
            $safe_machine_fixed_ip = "none";
        }

        // Check the serial
        $safe_machine_serial = safe_serial("machine_serial");
        if($safe_machine_serial === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid chassis serial number.";
            return $json;
        }
        $r = mysqli_query($con, "SELECT * FROM machines WHERE serial='$safe_machine_serial'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: machine with serial $safe_machine_serial doesn't exist.";
            return $json;
        }
        $machine = mysqli_fetch_array($r);
        $machine_status  = $machine["status"];
        $machine_id      = $machine["id"];
        $machine_cluster = $machine["cluster"];

        // Check status of that machine
        if($machine_status != "live"){
            $json["status"] = "error";
            $json["message"] = "Error: machine isn't running live image.";
            return $json;
        }
        if(!is_null($machine["cluster"])){
            $json["status"] = "error";
            $json["message"] = "Error: machine already enrolled in a cluster.";
            return $json;
        }

        if($machine["cluster"] !== NULL){
            $json["status"] = "error";
            $json["message"] = "Error: machine with serial $safe_machine_serial is already enrolled.";
            return $json;
        }

        // Check cluster name and fetch its id
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $r = mysqli_query($con, "SELECT * FROM clusters WHERE name='$safe_cluster_name'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name $safe_cluster_name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $safe_cluster_id     = $cluster["id"];

        // Check role name
        $safe_role_name = safe_fqdn("role_name");
        if($safe_role_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid role name.";
            return $json;
        }
        $r = mysqli_query($con, "SELECT id FROM roles WHERE name='$safe_role_name'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: role name $safe_role_name doesn't exist.";
            return $json;
        }
        $role = mysqli_fetch_array($r);
        $safe_role_id = $role["id"];

        // Check location name
        $safe_location_name = safe_fqdn("location_name");
        if($safe_location_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid location name.";
            return $json;
        }
        $r = mysqli_query($con, "SELECT id FROM locations WHERE name='$safe_location_name'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: location name $safe_location_name doesn't exist.";
            return $json;
        }
        $location = mysqli_fetch_array($r);
        $safe_location_id = $location["id"];

        $json = add_node_to_cluster($con, $conf, $machine_id, $safe_cluster_id, $safe_role_name, $safe_location_id, $safe_machine_fixed_ip);
        return $json;
        break;
    case "location_list":
        $r = mysqli_query($con, "SELECT * FROM locations ORDER BY id");
        $n = mysqli_num_rows($r);
        $json["data"] = [];
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;
    case "location_create":
        # Validate location name
        $safe_location_name = safe_fqdn("name");
        if($safe_location_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: location name format.";
            return $json;
        }
        $q = "SELECT * FROM locations WHERE name='$safe_location_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 0){
            $json["status"] = "error";
            $json["message"] = "Error: location name already exists.";
            return $json;
        }
        # Validate swiftregion
        $safe_swiftregion_name = safe_fqdn("swiftregion");
        if($safe_swiftregion_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: swiftregion name format.";
            return $json;
        }
        $q = "SELECT * FROM swiftregions WHERE name='$safe_swiftregion_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: swiftregion name not found.";
            return $json;
        }

        $r = mysqli_query($con, "INSERT INTO locations (name, swiftregion) VALUES ('$safe_location_name', '$safe_swiftregion_name')");
        return $json;
        break;
    case "location_delete":
        # Validate location name
        $safe_location_name = safe_fqdn("name");
        if($safe_location_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: location name format.";
            return $json;
        }
        $q = "SELECT * FROM locations WHERE name='$safe_location_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: location name not found.";
            return $json;
        }
        $a = mysqli_fetch_array($r);

        $q = "SELECT * FROM networks WHERE location_id='".$a["id"]."'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $json["status"] = "error";
            $json["message"] = "Error: cannot delete location, sone networks are using it.";
            return $json;
        }

        $r = mysqli_query($con, "DELETE FROM locations WHERE name='$safe_location_name'");
        return $json;
        break;
    case "swiftregion_list":
        $r = mysqli_query($con, "SELECT * FROM swiftregions ORDER BY id");
        $n = mysqli_num_rows($r);
        $json["data"] = [];
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;
    case "swiftregion_create":
        # Validate swiftregion name
        $safe_swiftregion_name = safe_fqdn("name");
        if($safe_swiftregion_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: swiftregion name format.";
            return $json;
        }
        $q = "SELECT * FROM swiftregions WHERE name='$safe_swiftregion_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 0){
            $json["status"] = "error";
            $json["message"] = "Error: swiftregion name already exists.";
            return $json;
        }
        $q = "INSERT INTO swiftregions (name) VALUES ('$safe_swiftregion_name')";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con) . " with query $q";
            return $json;
        }
        return $json;
        break;
    case "swiftregion_delete":
        # Validate swiftregion name
        $safe_swiftregion_name = safe_fqdn("name");
        if($safe_swiftregion_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: swiftregion name format.";
            return $json;
        }
        $q = "SELECT * FROM swiftregions WHERE name='$safe_swiftregion_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: swiftregion name not found.";
            return $json;
        }
        $q = "SELECT * FROM locations WHERE swiftregion='$safe_swiftregion_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $json["status"] = "error";
            $json["message"] = "Error: cannot delete swift region: some location (aka: swift zones) are using it.";
            return $json;
        }
        $r = mysqli_query($con, "DELETE FROM swiftregions WHERE name='$safe_swiftregion_name'");
        return $json;
        break;
    case "machine_reboot_on_hdd":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        if($machine["status"] == "firstboot" || $machine["status"] == "installed"){
            $json["message"] = "Warning: machine already started on HDD.";
            return $json;
        }

        ipmi_set_boot_device($con, $conf, $machine["id"], "disk");

        # Fix status in db
        $r = mysqli_query($con, "UPDATE machines SET status='firstboot' WHERE serial='$safe_machine_serial'");
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        # Perform reboot
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], "shutdown -r now");
        return $json;
        break;
    case "machine_reboot_on_live":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        if($machine["status"] == "live"){
            $json["message"] = "Warning: machine already started on Live image.";
            return $json;
        }

        ipmi_set_boot_device($con, $conf, $machine["id"], "pxe");

        # Fix status in db
        $q = "UPDATE machines SET status='bootinglive' WHERE serial='$safe_machine_serial'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], "shutdown -r now");
        return $json;
        break;
    case "hpe_ilo_license_install":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        # Add the ILO license if we have the /root/License.xml file (should be present in the Live OS only)
        $cmd = "if [ -e /root/License.xml ] ; then hponcfg -f /root/License.xml ; fi";
        $json["message"] .= "\n$cmd";
        $out = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
        $json["message"] .= "\n$out";

        return $json;
        break;
    case "activate_ipmi_over_lan":
    case "hpe_activate_ipmi_over_lan":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        machine_activate_ipmi_over_lan($con, $conf, $machine);

# This is the old way, but since HPONCFG is deprecated, let's not use it anymore.
#        # Add the ILO license if we have the /root/License.xml file (should be present in the Live OS only)
#        $cmd = "echo '<RIBCL VERSION=\\\"2.0\\\"><LOGIN USER_LOGIN=\\\"admin\\\" PASSWORD=\\\"password\\\"><RIB_INFO mode=\\\"write\\\"><MOD_GLOBAL_SETTINGS><IPMI_DCMI_OVER_LAN_ENABLED VALUE=\\\"Y\\\"/></MOD_GLOBAL_SETTINGS></RIB_INFO></LOGIN></RIBCL>' >set-ipmi-on.xml ; hponcfg -f set-ipmi-on.xml ; rm set-ipmi-on.xml";
#        $json["message"] .= "\n$cmd";
#        $out = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
#        $json["message"] .= "\n$out";

        return $json;
        break;
    case "ipmi_cmd":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        if(!isset($_REQUEST["cmd"])){
            $json["status"] = "error";
            $json["message"] = "Error: please specify a command as argument.";
            return $json;
        }
        $command = $_REQUEST["cmd"];

        $out = ipmi_send_command($con, $conf, $machine["id"], $command);
        $json["message"] = $out;
        return $json;
        break;
    case "ipmi_assign_ip":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];
        $machine_id = $machine["id"];

        if(!isset($_REQUEST["ipmi_network"])){
            $json["status"] = "error";
            $json["message"] = "Error: please specify an IPMI network as argument.";
            return $json;
        }
        $safe_ipmi_network_name = safe_fqdn("ipmi_network");
        if($safe_ipmi_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: ipmi_network format is wrong.";
            return $json;
        }

        $q = "SELECT * FROM networks WHERE name='$safe_ipmi_network_name'";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cannot find IPMI network.";
            return $json;
        }
        $a = mysqli_fetch_array($r);
        $ipmi_net_id = $a['id'];
        $ipmi_net_ipaddr = $a['ip'];
        $net_iplong = ip2long($ipmi_net_ipaddr);
        $ipmi_net_def_gateway = long2ip($net_iplong+1);

        # Delete the current machine's IPMI IP address from the ips table
        # before we reassign one.
        $q = "SELECT * FROM ips WHERE machine='$machine_id' AND usefor='ipmi'";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        if($n == 1){
            $q = "DELETE FROM ips WHERE machine='$machine_id' AND usefor='ipmi'";
            $r = mysqli_query($con, $q);
        }
        $ret = reserve_ip_address($con, $conf, $ipmi_net_id, $machine_id, "ipmi");
        if($ret["status"] == "success"){
            $q = "SELECT INET_NTOA(ips.ip) as ipaddr FROM ips WHERE machine='$machine_id' AND usefor='ipmi'";
            $r = mysqli_query($con, $q);
            $a = mysqli_fetch_array($r);
            $ipaddr = $a["ipaddr"];
            # We must set dhcp_ip to avoid that running the agent
            # sets the previous IPMI network through IP matching.
            $q = "UPDATE machines SET ipmi_addr='$ipaddr', ipmi_default_gw='$ipmi_net_def_gateway', dhcp_ip='0.0.0.0' WHERE id='$machine_id'";
            $r = mysqli_query($con, $q);
        }
        $json["status"] = "success";
        $json["message"] = "Successfuly re-assigned IPMI IP.";
        return $json;
        break;
    case "machine_wipe":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $machine_status  = $machine["status"];
        $machine_id      = $machine["id"];
        $machine_cluster = $machine["cluster"];

        // Check status of that machine
        if($machine_status != "live"){
            $json["status"] = "error";
            $json["message"] = "Error: machine isn't running live image.";
            return $json;
        }
        // Stop any running MD
        $cmd = "if [ -e /dev/md0 ] ; then mdadm --stop /dev/md0 ; mdadm --remove /dev/md0 ; fi";
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
        $json["message"] .= "\n$cmd";

        $cmd = "if [ -e /dev/md127 ] ; then mdadm --stop /dev/md127 ; mdadm --remove /dev/md127 ; fi";
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
        $json["message"] .= "\n$cmd";

        # Erase all LV listed by lvs
        $cmd = "TMPF=\$(mktemp -t wipe-all-lv.XXXXXX) ; lvs | sed '1d' >\$TMPF ; while read line ; do LV=\$(echo \$line | awk '{print \$1}') ; VG=\$(echo \$line | awk '{print \$2}') ; lvremove -f \"/dev/\$VG/\$LV\" ; done <\$TMPF ; rm -f \$TMPF";
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
        $json["message"] .= "\n$cmd";

        # Erase all VG listed by vgs
        $cmd = "TMPF=\$(mktemp -t wipe-all-vg.XXXXXX) ; vgs | sed '1d' >\$TMPF ; while read line ; do VG=\$(echo \$line | awk '{print \$1}') ; echo \"vgremove -f \$VG\" ; done <\$TMPF ; rm -f \$TMPF";
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
        $json["message"] .= "\n$cmd";

        // Wipe partition signatures from HDDs
        $q = "SELECT * FROM blockdevices WHERE machine_id='$machine_id'";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $hdd = mysqli_fetch_array($r);
            $name = $hdd["name"];
            $cmd = "wipefs --all -f /dev/${name}*";
            $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
            $json["message"] .= "\n$cmd";
        }
        $cmd = "partprobe";
        $ret = send_ssh_cmd($conf, $con, $machine["ipaddr"], $cmd);
        $json["message"] .= "\n$cmd";
        return $json;
        break;
    case "machine_display_install_cmd":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $machine_id = $machine["id"];

        $slave_install_return = slave_install_server_os_command($con, $conf, $machine_id);
        if($slave_install_return["status"] != "success"){
            $json["status"] = "error";
            $json["message"] = "Error while calculating installation command line for host $safe_machine_serial: ".$slave_install_return["message"];
            return $json;
        }
        $json["data"] .= "Running: ". $slave_install_return["cmd"];
        return $json;
        break;

    case "machine_install_os":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        if(file_exists("/var/lib/oci/ssl/ca") !== TRUE){
            $json["status"] = "error";
            $json["message"] = "Error: no /var/lib/oci/ssl/ca folder. Please make sure to run oci-root-ca-gen before installing any server.";
            return $json;
        }

        $json = oci_install_machine($con, $conf, $machine["id"]);

        return $json;
        break;

    case "machine_install_log":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $machine_id = $machine["id"];
        $machine_ip = $machine["ipaddr"];
        $machine_status = $machine["status"];
        if($machine_status == "live"){
            $json["data"] = "Machine is on live, not installing...";
        }elseif($machine_status == "installing"){
            $json["data"] = send_ssh_cmd($conf, $con, $machine_ip, "tail -n 80 /var/log/oci.log");
        }elseif($machine_status == "installed"){
            $json["data"] = send_ssh_cmd($conf, $con, $machine_ip, "oci-tail-last-puppet-log");
        }else{
            $json["data"] = "Machine is booting...";
        }
        return $json;
        break;
    case "machine_ip_list":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $json["data"] = Array();

        $q = "SELECT networks.name AS networkname, INET_NTOA(ips.ip) AS ipaddr, ips.usefor AS usefor FROM ips,machines,networks WHERE ips.machine=machines.id AND machines.serial='$safe_machine_serial' AND networks.id=ips.network";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;
    case "machine_ip_add":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        # Validate IP address
        $safe_machine_ip = safe_ipv4("ip_addr");
        if($safe_machine_ip === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not a valid IP address.";
            return $json;
        }
        $safe_ip_long = ip2long($safe_machine_ip);
        $q = "SELECT * FROM ips WHERE ip='$safe_ip_long'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n > 0){
            $json["status"] = "error";
            $json["message"] = "Error: IP address already in used.";
            return $json;
        }

        # Validate network name
        $safe_network_name = safe_fqdn("network_name");
        if($safe_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: network name format.";
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: network name not found.";
            return $json;
        }
        $network = mysqli_fetch_array($r);
        
        # Validate that the IP is within the network range
        $network_ip_min = $network["ip"];
        $network_ip_min_long = ip2long($network_ip_min);
        $inv_cidr = 32 - $network["cidr"];
        $netowrk_ip_max_long = $network_ip_min_long + pow(2, $inv_cidr) - 2;
        $network_ip_min_long += 1;
        $netowrk_ip_max_long -= 1;
        if($safe_ip_long < $network_ip_min_long || $safe_ip_long > $netowrk_ip_max_long){
            $json["status"] = "error";
            $json["message"] = "Error: IP not in range of network.";
            return $json;
        }
        $q = "INSERT INTO ips (network,ip,type,machine,usefor) VALUES ('".$network["id"]."', '".$safe_ip_long."','4','".$machine["id"]."','machine')";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        return $json;
        break;
    case "machine_ip_remove":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        # Validate IP address
        $safe_machine_ip = safe_ipv4("ip_addr");
        if($safe_machine_ip === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not a valid IP address.";
            return $json;
        }
        $safe_ip_long = ip2long($safe_machine_ip);
        $q = "SELECT * FROM ips WHERE ip='$safe_ip_long'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: machine with serial $safe_machine_serial doesn't own $safe_machine_ip.";
            return $json;
        }
        $ip = mysqli_fetch_array($r);
        $ip_id = $ip["id"];
        $q = "DELETE FROM ips WHERE id='$ip_id'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        return $json;
        break;

    case "machine_replace":
        $safe_old_serial = safe_serial("old_serial");
        if($safe_old_serial === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: old serial is not a valid machine serial number.";
            return $json;
        }
        $json = get_machine_from_serial_or_hostname($con, $conf, $safe_old_serial);
        if($json["status"] != "success"){ return $json; }
        $old_machine = $json["data"];
        $safe_old_machine_id       = $old_machine["id"];
        $safe_old_machine_serial   = $old_machine["serial"];
        $safe_old_machine_hostname = $old_machine["hostname"];
        $safe_old_puppet_status    = $old_machine["puppet_status"];
        $safe_old_role             = $old_machine["role"];
        $safe_old_cluster          = $old_machine["cluster"];
        $safe_old_location_id      = $old_machine["location_id"];

        $safe_old_use_ceph_if_available = $old_machine["use_ceph_if_available"];
        $safe_old_install_on_raid       = $old_machine["install_on_raid"];
        $safe_old_raid_type             = $old_machine["raid_type"];
        $safe_old_raid_dev0             = $old_machine["raid_dev0"];
        $safe_old_raid_dev1             = $old_machine["raid_dev1"];
        $safe_old_raid_dev2             = $old_machine["raid_dev2"];
        $safe_old_raid_dev3             = $old_machine["raid_dev3"];
        $safe_old_serial_console_dev    = $old_machine["serial_console_dev"];
        $safe_old_force_dhcp_agent      = $old_machine["force_dhcp_agent"];
        $safe_old_swift_store_account   = $old_machine["swift_store_account"];
        $safe_old_swift_store_container = $old_machine["swift_store_container"];
        $safe_old_swift_store_object    = $old_machine["swift_store_object"];
        $safe_old_servers_per_port      = $old_machine["servers_per_port"];
        $safe_old_network_chunk_size    = $old_machine["network_chunk_size"];
        $safe_old_disk_chunk_size       = $old_machine["disk_chunk_size"];
        $safe_old_lvm_backend_name      = $old_machine["lvm_backend_name"];
        $safe_old_cpu_allocation_ratio  = $old_machine["cpu_allocation_ratio"];
        $safe_old_ram_allocation_ratio  = $old_machine["ram_allocation_ratio"];
        $safe_old_disk_allocation_ratio = $old_machine["disk_allocation_ratio"];

        $safe_new_serial = safe_serial("new_serial");
        if($safe_new_serial === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: new serial is not a valid machine serial number.";
            return $json;
        }
        $json = get_machine_from_serial_or_hostname($con, $conf, $safe_new_serial);
        if($json["status"] != "success"){ return $json; }
        $new_machine = $json["data"];
        $safe_new_machine_id     = $new_machine["id"];
        $safe_new_machine_serial = $new_machine["serial"];

        # Move all interesting data from old machine to the new one
        $q = "UPDATE machines SET hostname='$safe_old_machine_hostname', puppet_status='$safe_old_puppet_status', role='$safe_old_role', cluster='$safe_old_cluster', location_id='$safe_old_location_id', use_ceph_if_available='$safe_old_use_ceph_if_available', install_on_raid='$safe_old_install_on_raid', raid_type='$safe_old_raid_type', raid_dev0='$safe_old_raid_dev0', raid_dev1='$safe_old_raid_dev1', raid_dev2='$safe_old_raid_dev2', raid_dev3='$safe_old_raid_dev3', serial_console_dev='$safe_old_serial_console_dev', force_dhcp_agent='$safe_old_force_dhcp_agent', swift_store_account='$safe_old_swift_store_account', swift_store_container='$safe_old_swift_store_container', swift_store_object='$safe_old_swift_store_object', servers_per_port='$safe_old_servers_per_port', network_chunk_size='$safe_old_network_chunk_size', disk_chunk_size='$safe_old_disk_chunk_size', lvm_backend_name='$safe_old_lvm_backend_name', cpu_allocation_ratio='$safe_old_cpu_allocation_ratio', ram_allocation_ratio='$safe_old_ram_allocation_ratio', disk_allocation_ratio='$safe_old_disk_allocation_ratio' WHERE id='$safe_new_machine_id'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con) . " line ".__LINE__." file ".__FILE__;
            return $json;
        }

        # Move all IPs of the old machine to the new one
        $q = "UPDATE ips SET machine='$safe_new_machine_id' WHERE machine='$safe_old_machine_id' AND usefor='machine'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con) . " line ".__LINE__." file ".__FILE__;
            return $json;
        }

        # Destroy old machine...
        $json = machine_destroy($con, $conf, $old_machine["id"]);

        return $json;
        break;
    case "ipmi_assign_check":
        $json = check_if_machines_on_ipmi_network($con, $conf);
        return $json;
        break;
    case "cluster_list":
        $q = "SELECT * FROM clusters";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $json["data"] = Array();
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;
    case "cluster_create":
        // Validate name
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 0){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name already exists.";
            return $json;
        }

        // Validate domain
        $safe_domain_name = safe_fqdn("domain");
        if($safe_domain_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid domain name.";
            return $json;
        }
        $json = new_cluster($con, $conf, $safe_cluster_name, $safe_domain_name);
        return $json;
        break;

    case "cluster_delete":
        // Validate name
        $safe_cluster_name = safe_fqdn("name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);

        # Check if some machines are in the cluster
        $q = "SELECT cluster FROM machines WHERE cluster='".$cluster["id"]."'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $json["status"] = "error";
            $json["message"] = "Error: cannot delete cluster: some machines are using it. Remove these machines first.";
            return $json;
        }

        # Check if some networks are in the cluster
        $q = "SELECT cluster FROM networks WHERE cluster='".$cluster["id"]."'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $json["status"] = "error";
            $json["message"] = "Error: cannot delete cluster: some networks are using it. Remove these networks first.";
            return $json;
        }

        return cluster_delete($con, $conf, $safe_cluster_name);
        break;

    case "cluster_show_networks":
        // Validate name
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $cluster_id = $cluster["id"];

        $q = "SELECT * FROM networks WHERE cluster='$cluster_id'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;

    case "cluster_show_machines":
        // Validate name
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $cluster_id = $cluster["id"];

        $q = "SELECT * FROM machines WHERE cluster='$cluster_id'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;

    ### Filebeat hosts management
    case "filebeat_output_host_list":
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $safe_cluster_id = $cluster["id"];

        $q = "SELECT * FROM filebeathosts WHERE cluster='$safe_cluster_id'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n == 0){
            $json["data"] = Array();
        }else{
            for($i=0;$i<$n;$i++){
                $a = mysqli_fetch_array($r);
                $cluster_id = $a["cluster"];
                $qc = "SELECT name FROM clusters WHERE id='$cluster_id'";
                $rc = mysqli_query($con, $qc);
                if($rc === FALSE){
                    $json["status"] = "error";
                    $json["message"] = mysqli_error($con);
                    return $json;
                }
                $nc = mysqli_num_rows($rc);
                if($nc != 1){
                    $json["status"] = "error";
                    $json["message"] = "Cannot find cluster with ID $cluster_id: please clean-up your filebeathosts table.";
                    return $json;
                }
                $ac = mysqli_fetch_array($rc);
                $a["cluster_name"] = $ac["name"];

                $json["data"][] = $a;
            }
        }
        
        return $json;
        break;
    case "filebeat_output_host_create":
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }

        $safe_filebeat_host = safe_fqdn("filebeat_host");
        if($safe_filebeat_host === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid filebeat host.";
            return $json;
        }

        $safe_filebeat_port = safe_int("filebeat_port");
        if($safe_filebeat_port === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid filebeat host.";
            return $json;
        }

        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $safe_cluster_id = $cluster["id"];

        $q = "SELECT * FROM filebeathosts WHERE cluster='$safe_cluster_id' AND hostname='$safe_filebeat_host' AND port='$safe_filebeat_port'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n >= 1){
            $json["status"] = "error";
            $json["message"] = "Error: filebeat host already exist for this cluster.";
            return $json;
        }

        $q = "INSERT INTO filebeathosts (cluster, hostname, port) VALUES ('$safe_cluster_id', '$safe_filebeat_host', '$safe_filebeat_port')";
        $r = mysqli_query($con, $q);

        return $json;
        break;
    case "filebeat_output_host_delete":
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }

        $safe_filebeat_host = safe_fqdn("filebeat_host");
        if($safe_filebeat_host === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid filebeat host.";
            return $json;
        }

        $safe_filebeat_port = safe_int("filebeat_port");
        if($safe_filebeat_port === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid filebeat host.";
            return $json;
        }

        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: cluster name doesn't exist.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $safe_cluster_id = $cluster["id"];

        $q = "SELECT * FROM filebeathosts WHERE cluster='$safe_cluster_id' AND hostname='$safe_filebeat_host' AND port='$safe_filebeat_port'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: filebeat host does not exist: cannot delete.";
            return $json;
        }

        $q = "DELETE FROM filebeathosts WHERE cluster='$safe_cluster_id' AND hostname='$safe_filebeat_host' AND port='$safe_filebeat_port'";
        $r = mysqli_query($con, $q);

        return $json;
        break;

    case "network_list":
        $q = "SELECT networks.id AS id,networks.name AS name,networks.ip AS ip,networks.cidr AS cidr,networks.is_public AS is_public,networks.cluster AS cluster,networks.role AS role,networks.vip_usage AS vip_usage,networks.iface1 AS iface1,networks.iface2 AS iface2,networks.lldp_match AS lldp_match,networks.bridgename AS bridgename,networks.vlan AS vlan,networks.mtu AS mtu,locations.name AS location, networks.ipmi_match_addr AS ipmi_match_addr, networks.ipmi_match_cidr AS ipmi_match_cidr, networks.ipmi_mode AS ipmi_mode, networks.first_ip AS first_ip, networks.last_ip AS last_ip FROM networks,locations WHERE locations.id=networks.location_id";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $a["first_ip"] = long2ip($a["first_ip"]);
            $a["last_ip"]  = long2ip($a["last_ip"]);
            if(is_null($a["cluster"])){
                $a["cluster_name"] = "-";
            }else{
                $qc = "SELECT name FROM clusters WHERE id='". $a["cluster"] ."'";
                $rc = mysqli_query($con, $qc);
                $nc = mysqli_num_rows($rc);
                if($nc == 0){
                    $a["cluster_name"] = "-";
                }else{
                    $ac = mysqli_fetch_array($rc);
                    $a["cluster_name"] = $ac["name"];
                }
            }
            $json["data"][$i] = $a;
        }
        return $json;
        break;

    case "network_delete":
        # Validate network name
        $safe_network_name = safe_fqdn("name");
        if($safe_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: network name format.";
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: network name not found.";
            return $json;
        }
        $network = mysqli_fetch_array($r);
        $r = mysqli_query($con, "DELETE FROM ips WHERE network='".$network["id"]."'");
        $r = mysqli_query($con, "DELETE FROM networks WHERE name='$safe_network_name'");
        return $json;
        break;

    case "new_network":
        // Check cluster name
        $safe_network_name = safe_fqdn("name");
        if($safe_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid network name.";
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 0){
            $json["status"] = "error";
            $json["message"] = "Error: network name already exists.";
            return $json;
        }

        // Check location
        $safe_location_name = safe_fqdn("location");
        if($safe_location_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid location name.";
        }
        $q = "SELECT * FROM locations WHERE name='$safe_location_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: location name doesn't exist. $q";
            return $json;
        }
        $location = mysqli_fetch_array($r);
        $safe_location_id = $location["id"];

        // Check IP
        $safe_network_ip = safe_ipv4("ipaddr");
        if($safe_network_ip === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: wrong ipaddr param.";
            return $json;
        }

        // Check mask
        $safe_cidr_mask = safe_int("cidr_mask");
        if($safe_cidr_mask === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: wrong cidr param.";
            return $json;
        }
        if($safe_cidr_mask > 32 || $safe_cidr_mask < 8){
            $json["status"] = "error";
            $json["message"] = "Error: CIDR mask must be between 8 and 32.";
            return $json;
        }

        // Check is_public
        if(!isset($_REQUEST["is_public"])){
            $json["status"] = "error";
            $json["message"] = "Error: is_public not set.";
            return $json;
        }
        if($_REQUEST["is_public"] == "yes"){
            $safe_is_public = "yes";
        }else{
            $safe_is_public = "no";
        }

        if($safe_cidr_mask == 32){
            $first_ip = ip2long($safe_network_ip);
            $last_ip = ip2long($safe_network_ip);
        }elseif($safe_cidr_mask == 31){
            $first_ip = ip2long($safe_network_ip);
            $last_ip = ip2long($safe_network_ip) + 1;
        }elseif($safe_cidr_mask == 30){
            $first_ip = ip2long($safe_network_ip) +1;
            $last_ip = ip2long($safe_network_ip) + 2;
        }else{
            $number_of_ip = 2 ** (32 - $safe_cidr_mask);
            $first_ip = ip2long($safe_network_ip) + 2;
            $last_ip = ip2long($safe_network_ip) + $number_of_ip - 2;
        }

        $q = "INSERT INTO networks (name, location_id, ip, cidr, is_public, first_ip, last_ip) VALUES ('$safe_network_name', '$safe_location_id', '$safe_network_ip', '$safe_cidr_mask', '$safe_is_public', '$first_ip', '$last_ip')";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = "Query: $q error: ".mysqli_error($con);
            return $json;
        }
        return $json;
        break;

    case "network_set":
        // Check network name is valid and exists
        $safe_network_name = safe_fqdn("network_name");
        if($safe_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid network name.";
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Cannot find network by that name.";
            return $json;
        }
        $network = mysqli_fetch_array($r);

        $update = "";

        if(isset($_REQUEST["role"])){
            switch($_REQUEST["role"]){
            case "all":
                $safe_role_name = "all";
                break;
            case "vm-net":
                $safe_role_name = "vm-net";
                break;
            case "ovs-bridge":
                $safe_role_name = "ovs-bridge";
                break;
            case "ceph-cluster":
                $safe_role_name = "ceph-cluster";
                break;
            case "ipmi":
                $safe_role_name = "ipmi";
                break;
            case "vip":
                $safe_role_name = "vip";
                break;
            default:
                $safe_role_name = safe_fqdn("role");
                if($safe_role_name === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong role name format.";
                    return $json;
                }
                $q = "SELECT * FROM roles WHERE name='$safe_role_name'";
                $r = mysqli_query($con, $q);
                if($r === FALSE){
                    $json["status"] = "error";
                    $json["message"] = mysqli_error($con);
                    return $json;
                }
                $n = mysqli_num_rows($r);
                if($n != 1){
                    $json["status"] = "error";
                    $json["message"] = "Error: no role by that name.";
                    return $json;
                }
                break;
            }
            $update .= "role='$safe_role_name'";
        }

        if(isset($_REQUEST["vip_usage"])){
            switch($_REQUEST["vip_usage"]){
            case "controller":
            case "messaging":
            case "sql":
            case "sqlmsg":
                $safe_vip_usage = $_REQUEST["vip_usage"];
                break;
            default:
                $json["status"] = "error";
                $json["message"] = "Wrong VIP usage name.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "vip_usage='$safe_vip_usage'";
        }

        if(isset($_REQUEST["iface1_name"])){
            $safe_eth1_name = safe_ethname("iface1_name");
            if($safe_eth1_name === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong eth1 name format here.";
                    return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "iface1='$safe_eth1_name'";
        }

        if(isset($_REQUEST["lldp_match"])){
            $safe_lldp_match = safe_hostname_with_wildcard("lldp_match");
            if($safe_lldp_match === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong lldp-match name format here.";
                    return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "lldp_match='$safe_lldp_match'";
        }

        if(isset($_REQUEST["iface2_name"])){
            $safe_eth2_name = safe_ethname("iface2_name");
            if($safe_eth2_name === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong eth2 name format.";
                    return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "iface2='$safe_eth2_name'";
        }

        if(isset($_REQUEST["ip"])){
            $safe_ip = safe_ipv4("ip");
            if($safe_ip === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong ip address format.";
                    return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "ip='$safe_ip'";
        }else{
            $safe_ip = $network["ip"];
        }

        if(isset($_REQUEST["cidr"])){
            $safe_cidr = safe_int("cidr");
            if($safe_cidr === FALSE || $safe_cidr < 0 || $safe_cidr > 32){
                    $json["status"] = "error";
                    $json["message"] = "Wrong cidr format.";
                    return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "cidr='$safe_cidr'";
        }else{
            $safe_cidr = $network["cidr"];
        }

        if(isset($_REQUEST["is_public"])){
            if($_REQUEST["is_public"] == "yes"){
                $ispublic = "yes";
            }else{
                $ispublic = "no";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "is_public='$ispublic'";
        }

        if(isset($_REQUEST["vlan"])){
            if($_REQUEST["vlan"] == "null" || $_REQUEST["vlan"] == "0"){
                if($update != ""){
                    $update .= ", ";
                }
                $update .= "vlan=null";
            }else{
                $safe_vlan = safe_int("vlan");
                if($safe_vlan === FALSE || $safe_vlan < 1 || $safe_vlan > 70000){
                        $json["status"] = "error";
                        $json["message"] = "Wrong vlan format.";
                        return $json;
                }
                if($update != ""){
                    $update .= ", ";
                }
                $update .= "vlan='$safe_vlan'";
            }
        }

        if(isset($_REQUEST["mtu"])){
            $safe_mtu = safe_int("mtu");
            if($safe_mtu === FALSE || $safe_mtu < 0 || $safe_mtu > 9999){
                $json["status"] = "error";
                $json["message"] = "Wrong mtu format.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "mtu='$safe_mtu'";
        }

        if(isset($_REQUEST["location"])){
            $safe_location = safe_fqdn("location");
            if($safe_location === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong location format.";
                return $json;
            }
            $q = "SELECT * FROM locations WHERE name='$safe_location'";
            $r = mysqli_query($con, $q);
            if($r === FALSE){
                $json["status"] = "error";
                $json["message"] = mysqli_error($con);
                return $json;
            }
            $n = mysqli_num_rows($r);
            if($n != 1){
                $json["status"] = "error";
                $json["message"] = "Error: location name not found.";
                return $json;
            }
            $location = mysqli_fetch_array($r);
            $location_id = $location["id"];
            if($update != ""){
                $update .= ", ";
            }
            $update .= "location_id='$location_id'";
        }
        if(isset($_REQUEST["bridgename"])){
            $safe_bridgename = safe_fqdn("bridgename");
            if($safe_bridgename === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong bridge name format.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "bridgename='$safe_bridgename'";
        }

        # IPMI dhcp network matching params
        if(isset($_REQUEST["ipmi_match_addr"])){
            $safe_ipmi_match_addr = safe_ipv4("ipmi_match_addr");
            if($safe_ipmi_match_addr === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong ipmi_match_addr format.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "ipmi_match_addr='$safe_ipmi_match_addr'";
        }
        if(isset($_REQUEST["ipmi_match_cidr"])){
            $safe_ipmi_match_cidr = safe_int("ipmi_match_cidr");
            if($safe_ipmi_match_cidr === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong ipmi_match_cidr format.";
                return $json;
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "ipmi_match_cidr='$safe_ipmi_match_cidr'";
        }

        if(isset($_REQUEST["ipmi_mode"])){
            if($_REQUEST["ipmi_mode"] == "ocimanaged"){
                $safe_ipmi_mode = "ocimanaged";
            }else{
                $safe_ipmi_mode = "externaldhcp";
            }
            if($update != ""){
                $update .= ", ";
            }
            $update .= "ipmi_mode='$safe_ipmi_mode'";
        }

        if(!isset($safe_ip)){
            $safe_ip = $network["ip"];
        }
        if(!isset($safe_cidr)){
            $safe_cidr = $network["cidr"];
        }

        $number_of_ip = 2 ** (32 - $safe_cidr);
        if($safe_cidr == 32){
            $net_first_ip = ip2long($safe_ip);
            $net_last_ip = ip2long($safe_ip);
        }else{
            $net_first_ip = ip2long($safe_ip) + 2;
            $net_last_ip = ip2long($safe_ip) + $number_of_ip - 2;
        }

        if( isset($_REQUEST["last_ip"]) && !isset($_REQUEST["first_ip"]) || !isset($_REQUEST["last_ip"]) && isset($_REQUEST["first_ip"]) ){
            $json["status"] = "error";
            $json["message"] = "You cannot set first IP without last IP, or last IP without first IP.";
            return $json;
        }

        if((isset($_REQUEST["ip"]) || isset($_REQUEST["cidr"])) && !isset($_REQUEST["first_ip"])){
            # If we're setting up network IP or CIDR without supplying first and last IP,
            # then we must use the automatically calculated values.
            $update .= ", first_ip='$net_first_ip', last_ip='$net_last_ip'";
        }else{
            if(isset($_REQUEST["first_ip"])){
                $safe_first_ip = safe_ipv4("first_ip");
                if($safe_first_ip === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong first_ip format.";
                    return $json;
                }
                if($update != ""){
                    $update .= ", ";
                }
                $safe_first_ip_long = ip2long($safe_first_ip);
                # Check if the IP is in the range
                if($safe_first_ip_long < $net_first_ip || $safe_first_ip_long > $net_last_ip){
                    $json["status"] = "error";
                    $json["message"] = "Specified network first IP address is out of the network range line ".__LINE__." file ".__FILE__.".";
                }
                $update .= "first_ip='$safe_first_ip_long'";
            }

            if(isset($_REQUEST["last_ip"])){
                $safe_last_ip = safe_ipv4("last_ip");
                if($safe_last_ip === FALSE){
                    $json["status"] = "error";
                    $json["message"] = "Wrong last_ip format.";
                    return $json;
                }
                if($update != ""){
                    $update .= ", ";
                }
                $safe_last_ip_long = ip2long($safe_last_ip);
                # Check if the IP is in the range
                if($safe_last_ip_long < $net_first_ip || $safe_last_ip_long > $net_last_ip){
                    $json["status"] = "error";
                    $json["message"] = "Specified network first IP address is out of the network range line ".__LINE__." file ".__FILE__.".";
                    return $json;
                }
                $update .= "last_ip='$safe_last_ip_long'";
            }
            if($safe_first_ip_long > $safe_last_ip_long){
                $json["status"] = "error";
                $json["message"] = "Specified first IP is greater than last IP.";
                return $json;
            }
        }
        $q = "UPDATE networks SET $update WHERE name='$safe_network_name'";
        if($update != ""){
            $r = mysqli_query($con, $q);
        }
        return $json;
        break;

    case "network_add":
        // Check network name is valid and exists
        $safe_network_name = safe_fqdn("network_name");
        if($safe_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid network name.";
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Cannot find network by that name.";
            return $json;
        }

        // Validate cluster name and fetch its id
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid cluster name.";
            return $json;
        }
        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Cannot find cluster by that name.";
            return $json;
        }
        $cluster = mysqli_fetch_array($r);
        $safe_cluster_id = $cluster["id"];

        // Check role name
        $safe_role_name = safe_fqdn("role_name");
        if($safe_role_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid role name.";
            return $json;
        }
        if($safe_role_name == "all" || $safe_role_name == "vm-net" || $safe_role_name == 'ovs-bridge' || $safe_role_name == 'ceph-cluster' || $safe_role_name == 'ipmi' || $safe_role_name == 'vip'){
            $sql_role = "'$safe_role_name'";
        }else{
            $r = mysqli_query($con, "SELECT id FROM roles WHERE name='$safe_role_name'");
            if($r === FALSE){
                $json["status"] = "error";
                $json["message"] = mysqli_error($con);
                return $json;
            }
            $n = mysqli_num_rows($r);
            if($n != 1){
                $json["status"] = "error";
                $json["message"] = "Error: role name $safe_role_name doesn't exist.";
                return $json;
            }
            $sql_role = "'$safe_role_name'";
        }


        // Check network card 1 param
        $safe_iface1 = safe_ethname("iface1");
        if($safe_iface1 === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid iface 1 name.";
            return $json;
        }

        // Check network card 2 param
        $safe_iface2 = safe_ethname("iface2");
        if($safe_iface2 === FALSE){
            $json["status"] = "error";
            $json["message"] = "Error: not valid iface 2 name.";
            return $json;
        }

        $q = "UPDATE networks SET cluster='$safe_cluster_id', role=$sql_role, iface1='$safe_iface1', iface2='$safe_iface2' WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        $network = mysqli_fetch_array($r);
        // If role is controller or all, then assign a VIP
        if(($network["role"] == "controller" || $network["role"] == "all") && ($network["is_public"] == "yes") ){
            $ret = reserve_ip_address($con, $conf, $network["id"], 0, "vip");
            if($ret["status"] != "success"){
                $json["status"] = "error";
                $json["message"] = $ret["message"];
                return $json;
            }
        }
        if($network["is_public"] == "no" && $network["role"] != "ovs-bridge"){
            $ret = reserve_ip_to_all_slaves_of_network($con, $conf, $safe_cluster_id, $network["id"], $safe_role_name);
            if($ret["status"] != "success"){
                $json["status"] = "error";
                $json["message"] = $ret["message"];
                return $json;
            }
        }
        return $json;
        break;

    case "network_remove":
        $safe_network_name = safe_fqdn("network_name");
        if($safe_network_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Network name in wrong format.";
            return $json;
        }
        $q = "SELECT * FROM networks WHERE name='$safe_network_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Cannot find network by that ID.";
            return $json;
        }
        $network = mysqli_fetch_array($r);
        $safe_network_id = $network["id"];

        $q = "UPDATE networks SET cluster=NULL, role=NULL WHERE id='$safe_network_id'";
        $r = mysqli_query($con, $q);
        $q = "DELETE FROM ips WHERE network='$safe_network_id'";
        $r = mysqli_query($con, $q);
        return $json;
        break;

    case "machine_apply_ipmi":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $safe_machine_id = $machine["id"];

        $ipmi_username   = $machine["ipmi_username"];
        $ipmi_password   = $machine["ipmi_password"];
        $ipmi_addr       = $machine["ipmi_addr"];
        $ipmi_netmask    = $machine["ipmi_netmask"];
        $ipmi_default_gw = $machine["ipmi_default_gw"];
        if($ipmi_netmask == ''){
            $ipmi_netmask = "255.255.255.0";
        }
        if($ipmi_default_gw == ''){
            $cmd = "ipcalc " . $ipmi_addr . "/" . $ipmi_netmask ." | grep HostMin: | awk '{print \$2}'";
            $output = "";
            $return_var = 0;
            exec($cmd, $output, $return_var);
            $ipmi_default_gw = $output[0];
        }

        $ret = perform_ipmitool_cmd($con, $conf, $safe_machine_id, $ipmi_username, $ipmi_password, $ipmi_addr, $ipmi_default_gw, $ipmi_netmask);
        $json["message"] = $ret["message"];
        return $json;
        break;

    case "machine_set_ipmi":
        $safe_machine_serial = safe_serial("serial");
        if($safe_machine_serial === FALSE){
            $json["status"] = "error";
            $json["message"] = "Wrong machine serial number format.";
            return $json;
        }
        $q = "SELECT * FROM machines WHERE serial='$safe_machine_serial'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "No machine with serial $safe_machine_serial in database.";
            return $json;
        }
        $machine = mysqli_fetch_array($r);
        $safe_machine_id = $machine["id"];
        
        if(!isset($_REQUEST["ipmi_use"])){
            $json["status"] = "error";
            $json["message"] = "ipmi_use param not set.";
            return $json;
        }
        if($_REQUEST["ipmi_use"] != 'yes'){
            $q = "UPDATE machines SET ipmi_use='no' WHERE id='$safe_machine_id'";
            $r = mysqli_query($con, $q);
            return $json;
        }

        $safe_ipmi_addr = safe_fqdn("ipmi_addr");
        if($safe_ipmi_addr === FALSE){
            $safe_ipmi_addr = safe_ipv4("ipmi_addr");
            if($safe_ipmi_addr === FALSE){
                $json["status"] = "error";
                $json["message"] = "IPMI address in wrong format.";
                return $json;
            }
        }
        if(isset($_REQUEST["ipmi_default_gw"])){
            $safe_ipmi_default_gw = safe_ipv4("ipmi_default_gw");
            if($safe_ipmi_default_gw === FALSE){
                $json["status"] = "error";
                $json["message"] = "IPMI default gw in wrong format.";
                return $json;
            }
        }
        if(isset($_REQUEST["ipmi_netmask"])){
            $safe_ipmi_netmask = safe_ipv4("ipmi_netmask");
            if($safe_ipmi_netmask === FALSE){
                $json["status"] = "error";
                $json["message"] = "IPMI netmask in wrong format.";
                return $json;
            }
        }
        if(isset($_REQUEST["ipmi_call_chassis_bootdev"])){
            if($_REQUEST["ipmi_call_chassis_bootdev"] == "yes"){
                $safe_ipmi_call_chassis_bootdev = "yes";
            }else{
                $safe_ipmi_call_chassis_bootdev = "no";
            }
            $q = "UPDATE machines SET ipmi_call_chassis_bootdev='$safe_ipmi_call_chassis_bootdev' WHERE id='$safe_machine_id'";
            $r = mysqli_query($con, $q);
        }
        $safe_ipmi_port = safe_int("ipmi_port");
        if($safe_ipmi_port === FALSE){
            $out .= "IPMI port in wrong format.";
            return $out;
        }
        $safe_ipmi_username = safe_fqdn("ipmi_username");
        if($safe_ipmi_username === FALSE){
            $json["status"] = "error";
            $json["message"] = "IPMI username in wrong format.";
            return $json;
        }
        $safe_ipmi_password = safe_password("ipmi_password");
        if($safe_ipmi_password === FALSE){
            $json["status"] = "error";
            $json["message"] = "IPMI password in wrong format.";
            return $json;
        }
        if(isset($_REQUEST["perform_ipmitool_cmd"]) && $_REQUEST["perform_ipmitool_cmd"] == "yes"){
            $machine_id = $machine["id"];
            perform_ipmitool_cmd($con, $conf, $machine_id, $safe_ipmi_username, $safe_ipmi_password, $safe_ipmi_addr, $safe_ipmi_default_gw, $safe_ipmi_netmask);
        }

        $q = "UPDATE machines SET ipmi_use='yes', ipmi_addr='$safe_ipmi_addr', ipmi_port='$safe_ipmi_port', ipmi_username='$safe_ipmi_username', ipmi_password='$safe_ipmi_password' WHERE id='$safe_machine_id'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        return $json;
        break;

    case "ipmi_show_cmd_console":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $cmd = "ipmitool -I lanplus -H " . $machine["ipmi_addr"] . " -p " . $machine["ipmi_port"] . " -U " . escapeshellarg($machine["ipmi_username"]) ." -P " . escapeshellarg($machine["ipmi_password"]) . " sol activate\n";
        $cmd .= "Or login with the web UI: https://" . $machine["ipmi_addr"];
        $json["message"] .= "\n$cmd";
        return $json;
        break;
    case "ipmi_reboot_on_hdd":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $machine_id    = $machine["id"];
        $ipmi_addr     = $machine["ipmi_addr"];
        $ipmi_port     = $machine["ipmi_port"];
        $ipmi_username = $machine["ipmi_username"];
        $ipmi_password = $machine["ipmi_password"];

        ipmi_set_boot_device($con, $conf, $machine_id, "disk");

        $r = mysqli_query($con, "UPDATE machines SET status='firstboot' WHERE serial='$safe_machine_serial'");

        $cmd = "ipmitool -I lanplus -H $ipmi_addr -p $ipmi_port -U " . escapeshellarg($ipmi_username) . " -P " . escapeshellarg($ipmi_password) . " power cycle";
        $output = "";
        $return_var = 0;
        exec($cmd, $output, $return_var);
        return $json;
        break;
    case "ipmi_reboot_on_live":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];
        $safe_machine_serial = $machine["serial"];

        $machine_id    = $machine["id"];
        $ipmi_addr     = $machine["ipmi_addr"];
        $ipmi_port     = $machine["ipmi_port"];
        $ipmi_username = $machine["ipmi_username"];
        $ipmi_password = $machine["ipmi_password"];

        ipmi_set_boot_device($con, $conf, $machine_id, "pxe");

        $r = mysqli_query($con, "UPDATE machines SET status='bootinglive' WHERE serial='$safe_machine_serial'");

        $cmd = "ipmitool -I lanplus -H $ipmi_addr -p $ipmi_port -U " . escapeshellarg($ipmi_username) . " -P " . escapeshellarg($ipmi_password) . " power cycle";
        $output = "";
        $return_var = 0;
        exec($cmd, $output, $return_var);
        return $json;
        break;
    case "swift_caculate_ring":
        $safe_cluster_name = safe_fqdn("cluster_name");
        if($safe_cluster_name === FALSE){
            $out .= "Wrong cluster_name format.";
            print($out);
            die();
        }

        $q = "SELECT * FROM clusters WHERE name='$safe_cluster_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "No cluster with name $safe_cluster_name in database.";
            return $json;
        }

        $cluster = mysqli_fetch_array($r);

        if(isset($_REQUEST["ec_only"]) && $_REQUEST["ec_only"] == "yes"){
            $safe_ec_only = "yes";
        }else{
            $safe_ec_only = "no";
        }

        if(isset($_REQUEST["initial_account_weight"])){
            $safe_initial_account_weight = safe_int("initial_account_weight");
            if($safe_initial_account_weight === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong initial account weight format.";
                return $json;                
            }
        }else{
            $safe_initial_account_weight = 1000;
        }

        if(isset($_REQUEST["initial_container_weight"])){
            $safe_initial_container_weight = safe_int("initial_container_weight");
            if($safe_initial_container_weight === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong initial container weight format.";
                return $json;
            }
        }else{
            $safe_initial_container_weight = 1000;
        }

        if(isset($_REQUEST["initial_object_weight"])){
            $safe_initial_object_weight = safe_int("initial_object_weight");
            if($safe_initial_object_weight === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong initial object weight format.";
                return $json;
            }
        }else{
            $safe_initial_object_weight = 1000;
        }

        $json["data"] = build_swift_ring($con, $conf, $cluster["id"], "no", $safe_initial_account_weight, $safe_initial_container_weight, $safe_initial_object_weight, $safe_ec_only);

        return $json;
        break;
    case "swift_add_machine_to_ring":
        $json = get_machine_from_serial_or_hostname($con, $conf);
        if($json["status"] != "success"){ return $json; }
        $machine = $json["data"];

        if(isset($_REQUEST["debug"]) && $_REQUEST["debug"] = "yes"){
            $debug="yes";
        }else{
            $debug="no";
        }

        if(isset($_REQUEST["ec_only"]) && $_REQUEST["ec_only"] == "yes"){
            $safe_ec_only = "yes";
        }else{
            $safe_ec_only = "no";
        }

        if(isset($_REQUEST["initial_account_weight"])){
            $safe_initial_account_weight = safe_int("initial_account_weight");
            if($safe_initial_account_weight === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong initial account weight format.";
                return $json;                
            }
        }else{
            $safe_initial_account_weight = 1000;
        }

        if(isset($_REQUEST["initial_container_weight"])){
            $safe_initial_container_weight = safe_int("initial_container_weight");
            if($safe_initial_container_weight === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong initial container weight format.";
                return $json;
            }
        }else{
            $safe_initial_container_weight = 1000;
        }

        if(isset($_REQUEST["initial_object_weight"])){
            $safe_initial_object_weight = safe_int("initial_object_weight");
            if($safe_initial_object_weight === FALSE){
                $json["status"] = "error";
                $json["message"] = "Wrong initial object weight format.";
                return $json;
            }
        }else{
            $safe_initial_object_weight = 1000;
        }

        $json["data"] = add_machine_to_swift_ring($con, $conf, $machine["id"], $debug, $safe_initial_account_weight, $safe_initial_container_weight, $safe_initial_object_weight, $safe_ec_only);
        
        return $json;
        break;
    case "role_list":
        $r = mysqli_query($con, "SELECT * FROM roles");
        $n = mysqli_num_rows($r);
        $json["data"] = array();
        for($i=0;$i<$n;$i++){
            $a = mysqli_fetch_array($r);
            $json["data"][$i] = $a;
        }
        return $json;
        break;
    case "role_create":
        $safe_role_name = safe_fqdn("name");
        if($safe_role_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Wrong role name format.";
            return $json;
        }
        $q = "SELECT * FROM roles WHERE name='$safe_role_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 0){
            $json["status"] = "error";
            $json["message"] = "Error: role name already exists.";
            return $json;
        }
        if($safe_role_name == "all" || $safe_role_name == "vm-net" || $safe_role_name == "ovs-bridge" || $safe_role_name == "ceph-cluster" || $safe_role_name == "ipmi" || $safe_role_name == "vip"){
            $json["status"] = "error";
            $json["message"] = "Error: this role is reserved for special networking purposes.";
            return $json;
        }
        $r = mysqli_query($con, "INSERT INTO roles (name) VALUES ('$safe_role_name')");
        return $json;
        break;
    case "role_delete":
        $safe_role_name = safe_fqdn("name");
        if($safe_role_name === FALSE){
            $json["status"] = "error";
            $json["message"] = "Wrong role name format.";
            return $json;
        }
        $q = "SELECT * FROM roles WHERE name='$safe_role_name'";
        $r = mysqli_query($con, $q);
        if($r === FALSE){
            $json["status"] = "error";
            $json["message"] = mysqli_error($con);
            return $json;
        }
        $n = mysqli_num_rows($r);
        if($n != 1){
            $json["status"] = "error";
            $json["message"] = "Error: no role by that name.";
            return $json;
        }
        $r = mysqli_query($con, "DELETE FROM roles WHERE name='$safe_role_name'");
        return $json;
        break;
    default:
        $json["status"] = "error";
        $json["message"] = "Error: no action by that name.";
        return $json;
        break;
    }
    
}

$out_json = api_actions($con,$conf);
print(json_encode($out_json) . "\n");
?>
