APIcall("GET", $SOCKET_SERVER_LOCATION . '/broadcast/provisioning', $data); } public function prepareProvision(): string { //$this->testSocket(); $current_database = $_ENV['MAIN_DATABASE_IP']; log_message('info', "***** ***** prepareProvision :: Working Database " . $current_database); log_message('info', "***** ***** prepareProvision :: Starting Port Allocation "); $this->allocatePortNo(); // allocate port for the container use log_message('info', "***** ***** prepareProvision :: Starting Product Database if Needed "); $this->prepareDataBase(); // allocate port for the container use log_message('info', "***** ***** prepareProvision :: Create needed DockerCompose Files "); $this->updateProvision(); log_message('info', "***** ***** prepareProvision :: Populate HAPROXY for URL "); $this->configureURL(); log_message('info', "***** ***** scheduleRefreshAction :: Refresh Requested Sites "); $this->scheduleRefreshAction(); return 0; } //PROVISION_MSQL_DATABASE_IP="172.16.4.96" //PROVISION_MSQL_DATABASE_USERNAME="root" //PROVISION_MSQL_DATABASE_PASSWORD="may12002!" //PROVISION_MSQL_DATABASE="wordpress" //PROVISION_MSQL_DATABASE_PORT="3307" private function prepareDataBase(): void { $servername = $_ENV['PROVISION_MSQL_DATABASE_IP'] . ":" . $_ENV['PROVISION_MSQL_DATABASE_PORT']; // "172.16.4.96:3307"; $database = $_ENV['PROVISION_MSQL_DATABASE']; //"wordpress"; $username = $_ENV['PROVISION_MSQL_DATABASE_USERNAME']; //"root"; $password = $_ENV['PROVISION_MSQL_DATABASE_PASSWORD']; //"may12002!"; // Create connection $conn = mysqli_connect($servername, $username, $password, $database); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } //echo "Connected successfully"; log_message('info', "***** ***** prepareDataBase :: Connected successfully "); $list_limit = 2; $mysql = "SELECT id, member_id, uid, internal_url,product_id,status,provision_port,updated FROM members_products WHERE db_status = 0 AND product_id IN ('A000004','A000003') AND provision_status = 0 ORDER BY updated ASC LIMIT " . $list_limit; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $memberID = $pr->member_id; $productId = $pr->product_id; $provisionUID = $pr->uid; $ContainerName = $this->generatedContainerName($productId, $pr->id); // $productId . str_pad($pr->id, 10, "0", STR_PAD_LEFT); $dbName = $this->generatedBlogDatabaseName($productId, $pr->id); // $ContainerName; // Create database $sql = "CREATE DATABASE $dbName"; if ($conn->query($sql) === TRUE) { // echo "Database created successfully"; log_message('info', "***** ***** prepareDataBase :: () Database created successfully "); $mysql = "UPDATE members_products SET updated=now() WHERE uid::TEXT = '" . $provisionUID . "'"; try { $query = $this->db->query($mysql); // $sql = "CREATE USER '" . $dbName . "'@'localhost' IDENTIFIED BY '" . $provisionUID . "'"; $sql = "CREATE USER '" . $dbName . "'@'%' IDENTIFIED BY '" . $provisionUID . "'"; $result = mysqli_query($conn, $sql); // $sql = "GRANT SELECT , INSERT , UPDATE , DELETE ON " . $dbName . " . * TO '" . $dbName . "'@'localhost' IDENTIFIED BY '" . $provisionUID . "'"; $sql = "GRANT CREATE, SELECT , INSERT , UPDATE , DELETE ON " . $dbName . " . * TO '" . $dbName . "'@'localhost' IDENTIFIED BY '" . $provisionUID . "'"; log_message('info', "***** ***** prepareDataBase :: GrantQuery === " . $sql); $result = mysqli_query($conn, $sql); $mysql = "UPDATE members_products SET updated=now(), db_status = db_status + 1 WHERE uid::TEXT = '" . $provisionUID . "'"; $query = $this->db->query($mysql); } catch (\Exception $e) { // echo 'Message: ' .$e->getMessage(); log_message('critical', "***** ***** prepareDataBase Error:: () " . $e->getMessage()); } } else { //echo "Error creating database: " . $conn->error; log_message('critical', "***** ***** prepareDataBase Error:: (Error creating database:) " . $conn->error); } } mysqli_close($conn); } private function generatedContainerName($productId, $provID) { return $productId . "-SVR-" . str_pad($provID, 10, "0", STR_PAD_LEFT); } private function generatedBlogDatabaseName($productId, $provID): string { return strtoupper($productId . str_pad($provID, 10, "0", STR_PAD_LEFT)); } public function updateProvision(): string { $list_limit = 1; // for noow $public_path = FCPATH; $ansible_folder = str_replace("public/", "ANSIBLE", $public_path); //$partMachineLocal = "/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $partMachineLocal = $_ENV['PATH_MACHINE_LOCAL']; // "/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; if (!is_dir($ansible_folder . "/parts")) { mkdir($ansible_folder . "/parts", 0700); } $mysql = "SELECT id, uid, internal_url,product_id,status,provision_port,updated, member_id, id AS subscription_id FROM members_products WHERE provision_port > 0 AND provision_status = 0 AND p_file = 0 ORDER BY updated ASC LIMIT " . $list_limit; $query = $this->db->query($mysql); // $num = $query->num_rows(); $provision_list = $query->getResult(); //$provision_list =[]; foreach ($provision_list as $pr) { $subscriptionId = $pr->subscription_id; $provisionPort = $pr->provision_port; $productId = $pr->product_id; // $provisionUID = $pr->uid; $subscriptionUId = $pr->uid; $memberID = $pr->member_id; $ContainerName = $this->generatedContainerName($productId, $pr->id); // $productId . str_pad($pr->id, 10, "0", STR_PAD_LEFT); $partFolder = $ansible_folder . "/parts/" . $subscriptionUId; $allocatedPort = $provisionPort; $this->updateToNow($subscriptionUId); if (!is_dir($partFolder)) { mkdir($partFolder, 0700); } // THIS PROVISONING COMPOSERS $composer_template_path = $ansible_folder . "/templates/composers/" . $productId . "/docker-compose.yml"; $composer_template_path_local = $partMachineLocal . $subscriptionUId; $prov_name = str_replace(".", "_", $pr->internal_url) . ".yml"; $template_file = $ansible_folder . "/templates/" . $pr->product_id . ".yml"; //Get the domposer template file $destinationHomeFolder = $_ENV['DESTINATION_HOME_FOLDER'] . $ContainerName; $composer_template_contents = file_get_contents($composer_template_path); // Do the processing $composer_template_contents = $this->prepareTemplateFile($composer_template_contents, $ContainerName, $allocatedPort, $subscriptionUId, $ansible_folder, $productId, $pr->internal_url, $pr->id); // GET THE TEMPLATE FOR THIS PROVISIONING $template_content = file_get_contents($template_file); $template_content_processed = str_replace("WHAT_HOST_IN_USE", $productId . "_SERVER", $template_content); $template_content_processed = str_replace("WHAT_PART_FOLDER", $partFolder, $template_content_processed); $template_content_processed = str_replace("DESTINATION_FOLDER", $destinationHomeFolder, $template_content_processed); $template_content_processed = str_replace("WHAT_PART_LOCAL", $composer_template_path_local, $template_content_processed); // depends on the local machine // CREATE PROVISOINING FILE $myfile = fopen($ansible_folder . "/" . $prov_name, "w") or die("Unable to open file!"); fwrite($myfile, $template_content_processed); fclose($myfile); $this->registerProvision($subscriptionId, $prov_name); $this->create_provision_action($memberID, $subscriptionUId, "Auto Configuration Started", false); } return 0; } private function assignProvideImageName($productId, $provisionUID): array { $PROVISION_IMAGE_NAME = ''; $PROVISION_IMAGE_FLAVOR = 'P' . rand(1, 6); // temporary - should be blank // let us confirm if we have a custom template for this line $provisionUID = trim($provisionUID); $mysql = "SELECT * FROM members_products WHERE uid::text = '$provisionUID'"; $query = $this->db->query($mysql); $provision_detail = $query->getResult(); if (count($provision_detail) > 0) { //var_dump($provision_detail[0]); $result = $provision_detail[0]; // Get results as an array of objects $product_template = $result->product_template; $custom_template = $result->custom_template; if ($product_template == '') { // No template assigned $imageData = $this->pickLatestImage($productId); if (count($imageData)) { $this->assignTemplateToProvision($provisionUID, $imageData["provision_uid"]); //stamp image on the provison $PROVISION_IMAGE_NAME = $imageData["provision_name"]; $PROVISION_IMAGE_FLAVOR = $imageData["flavor"]; } } if ($product_template != '') { // We have a template //$provision_name = $this->selectTemplateFromUID($product_template); $provision_data = $this->selectTemplateDetailsFromUID($product_template); if ($provision_data[0] != '') { $PROVISION_IMAGE_NAME = $provision_data[0]; // $provision_name; $PROVISION_IMAGE_FLAVOR = $provision_data[1]; } } if ($custom_template != '') { // We have a custom template $provision_name = $this->selectCustomnTemplateFromName($custom_template); if ($provision_name != '') { $PROVISION_IMAGE_NAME = $provision_name; $PROVISION_IMAGE_FLAVOR = ""; } } log_message('critical', "***** ***** assignProvideImageName ProductTemplate: $PROVISION_IMAGE_NAME CustomTemplate: $custom_template "); } log_message('critical', "***** ***** FINAL assignProvideImageName ProductTemplate: $PROVISION_IMAGE_NAME "); return [$PROVISION_IMAGE_NAME, $PROVISION_IMAGE_FLAVOR]; } private function readProductImageName($provisionUID): array { $PROVISION_IMAGE_NAME = ''; $PROVISION_IMAGE_FLAVOR = 'P' . rand(1, 6); // temporary - should be blank $provisionUID = trim($provisionUID); $mysql = "SELECT * FROM members_products WHERE uid::text = '$provisionUID'"; $query = $this->db->query($mysql); $provision_detail = $query->getResult(); if (count($provision_detail) > 0) { log_message('info', "***** ***** FINAL readProductImageName In Now "); $result = $provision_detail[0]; // Get results as an array of objects $product_template = $result->product_template; $custom_template = $result->custom_template; if ($product_template != '') { log_message('info', "***** ***** FINAL readProductImageName In Now 001"); $provision_data = $this->selectTemplateDetailsFromUID($product_template); if ($provision_data[0] != '') { $PROVISION_IMAGE_NAME = $provision_data[0]; // $provision_name; $PROVISION_IMAGE_FLAVOR = $provision_data[1]; } } if ($custom_template != '') { // We have a custom template log_message('info', "***** ***** FINAL readProductImageName In Now 002"); $provision_name = $this->selectCustomnTemplateFromName($custom_template); if ($provision_name != '') { $PROVISION_IMAGE_NAME = $provision_name; $PROVISION_IMAGE_FLAVOR = ""; } } log_message('critical', "***** ***** readProductImageName ProductTemplate: $PROVISION_IMAGE_NAME CustomTemplate: $custom_template "); return [$PROVISION_IMAGE_NAME, $PROVISION_IMAGE_FLAVOR]; } log_message('critical', "***** ***** FINAL readProductImageName ProductTemplate: $PROVISION_IMAGE_NAME "); return []; } private function selectCustomnTemplateFromName($custom_id) { $mysql = "SELECT * FROM custom_templates WHERE custom_id = '$custom_id'"; $query = $this->db->query($mysql); $template_detail = $query->getResult(); $provision_name = ''; if (count($template_detail) > 0) { //var_dump($provision_detail[0]); $result = $template_detail[0]; // Get results as an array of objects $provision_name = trim($result->provision_name); } return $provision_name; } private function selectTemplateDetailsFromUID($template_uid): array { $mysql = "SELECT * FROM products_templates WHERE uid::text = '$template_uid'"; $query = $this->db->query($mysql); $template_detail = $query->getResult(); $provision_name = ''; $provision_flavor = ''; if (count($template_detail) > 0) { //var_dump($provision_detail[0]); $result = $template_detail[0]; // Get results as an array of objects $provision_name = trim($result->provision_name); $provision_flavor = trim($result->flavor); } return [$provision_name, $provision_flavor]; } private function selectTemplateFromUID($template_uid) { $mysql = "SELECT * FROM products_templates WHERE uid::text = '$template_uid'"; $query = $this->db->query($mysql); $template_detail = $query->getResult(); $provision_name = ''; if (count($template_detail) > 0) { //var_dump($provision_detail[0]); $result = $template_detail[0]; // Get results as an array of objects $provision_name = trim($result->provision_name); } return $provision_name; } private function pickLatestImage($productId) { $mysql = "SELECT uid::text AS provision_uid,provision_name,flavor FROM products_templates WHERE product_id = trim('$productId') AND status = 1 ORDER BY id DESC limit 1"; $query = $this->db->query($mysql); $template_detail = $query->getResult(); $data = []; if (count($template_detail) > 0) { /// var_dump($template_detail[0]); $result = $template_detail[0]; // Get results as an array of objects $data["provision_uid"] = $result->provision_uid; $data["provision_name"] = $result->provision_name; $data["flavor"] = $result->flavor; } return $data; } private function assignTemplateToProvision($provisionUID, $provision_uid) { $mysql = "UPDATE members_products SET product_template='$provision_uid' WHERE uid::text = '$provisionUID' AND product_template = '' "; $this->db->query($mysql); return 0; } private function prepareTemplateFile($composer_template_contents, $ContainerName, $allocatedPort, $provisionUID, $ansible_folder, $productId, $internalUrl, $provID): string { // $PROVISION_IMAGE_NAME = match ($productId) { // "A000001" => "registry.chiefsoft.com/pweb/pweb-01-merms-pweb0006c:latest", // "A000002" => "registry.chiefsoft.com/bweb/bweb-01-merms-pweb0006c:latest", // default => '', // }; // $PROVISION_IMAGE_DATA = $this->assignProvideImageName($productId, $provisionUID); $PROVISION_IMAGE_NAME = $PROVISION_IMAGE_DATA[0]; // $this->assignProvideImageName($productId, $provisionUID); $PROVISION_IMAGE_FLAVOR = $PROVISION_IMAGE_DATA[1]; $partMachineLocal = $_ENV['PATH_MACHINE_LOCAL']; $SITE_CONTENTS_GATEWAY = $_ENV['SITE_CONTENTS_GATEWAY']; $SITE_CONTACT_GATEWAY = $_ENV['SITE_CONTACT_GATEWAY']; $MYSQL_PROVISION_DATABASE_PORT = $_ENV['PROVISION_MSQL_DATABASE_IP'] . ":" . $_ENV['PROVISION_MSQL_DATABASE_PORT']; // "172.16.4.96:3307"; $destinationHomeFolder = $_ENV['DESTINATION_HOME_FOLDER'] . $ContainerName; $CNT_DB_NAME = $this->generatedBlogDatabaseName($productId, $provID); $CNT_DB_USER_NAME = $CNT_DB_NAME; //"bloguser"; //$templateRandom = 'P' . rand(1, 6); $composer_template_contents = str_replace("WHAT_CONTAINER_NAME", $ContainerName, $composer_template_contents); $composer_template_contents = str_replace("DESTINATION_FOLDER", $destinationHomeFolder, $composer_template_contents); $composer_template_contents = str_replace("ALLOCATED_PORT", $allocatedPort, $composer_template_contents); // $composer_template_contents = str_replace("CNT_DB_NAME", $ContainerName, $composer_template_contents); $composer_template_contents = str_replace("CNT_DB_NAME", $CNT_DB_NAME, $composer_template_contents); $composer_template_contents = str_replace("CNT_DB_USER_NAME", $CNT_DB_USER_NAME, $composer_template_contents); $composer_template_contents = str_replace("CNT_DB_PASS", $provisionUID, $composer_template_contents); $composer_template_contents = str_replace("CNT_DB_DATA", $MYSQL_PROVISION_DATABASE_PORT, $composer_template_contents); $composer_template_contents = str_replace("PROVISION_UID_REPLACE", $provisionUID, $composer_template_contents); $composer_template_contents = str_replace("PROVISION_IMAGE_NAME_REPLACE", $PROVISION_IMAGE_NAME, $composer_template_contents); $composer_template_contents = str_replace("SITE_CONTENTS_URL_REPLACE", $SITE_CONTENTS_GATEWAY, $composer_template_contents); $composer_template_contents = str_replace("SITE_CONTACT_URL_REPLACE", $SITE_CONTACT_GATEWAY, $composer_template_contents); $composer_template_contents = str_replace("TEMPLATE_NAME_REPLACE", $PROVISION_IMAGE_FLAVOR, $composer_template_contents); try { //Save to the specific path $destination_composer_path = $ansible_folder . "/parts/" . $provisionUID . "/docker-compose.yml"; $composerFile = fopen($destination_composer_path, "w") or die("Unable to open file!"); fwrite($composerFile, $composer_template_contents); fclose($composerFile); } catch (\Exception $e) { log_message('critical', "***** ***** prepareTemplateFile Error:: () " . $e->getMessage()); } $composer_template_path = $ansible_folder . "/templates/composers/" . $productId . "/docker-compose.yml"; $composer_template_path_local = $partMachineLocal . $provisionUID; $prov_name = str_replace(".", "_", $internalUrl) . ".yml"; $template_file = $ansible_folder . "/templates/" . $productId . ".yml"; $partFolder = $ansible_folder . "/parts/" . $provisionUID; if (!is_dir($partFolder)) { mkdir($partFolder, 0700); } try { $template_content = file_get_contents($template_file); $template_content_processed = str_replace("WHAT_HOST_IN_USE", $productId . "_SERVER", $template_content); $template_content_processed = str_replace("WHAT_PART_FOLDER", $partFolder, $template_content_processed); $template_content_processed = str_replace("DESTINATION_FOLDER", $destinationHomeFolder, $template_content_processed); $template_content_processed = str_replace("WHAT_PART_LOCAL", $composer_template_path_local, $template_content_processed); // depends on the local machine // CREATE PROVISIONING FILE $myfile = fopen($ansible_folder . "/" . $prov_name, "w") or die("Unable to open file!"); fwrite($myfile, $template_content_processed); fclose($myfile); } catch (\Exception $e) { log_message('critical', "***** ***** prepareTemplateFile Error:: () " . $e->getMessage()); } // GET THE TEMPLATE FOR THIS PROVISIONING return $composer_template_contents; } private function scheduleRefreshAction(): void { $mysql = "SELECT * FROM member_product_refresh WHERE product_id IN ('A000001','A000002','A000006') AND status =0 LIMIT 1"; $query = $this->db->query($mysql); // $num = $query->num_rows(); $provision_list = $query->getResult(); //$provision_list =[]; foreach ($provision_list as $pr) { $subscriptionUId = $pr->subscription_uid; $this->db->query("UPDATE member_product_refresh SET status = status + 1 WHERE id = " . $pr->id); $this->auditProvisionPlans($subscriptionUId); if ($this->refreshProvision($subscriptionUId) == 100) { log_message('critical', "***** ***** scheduleRefreshAction Started:: () "); } } $mysql = "SELECT * FROM member_product_refresh WHERE product_id IN ('A000003','A000004') AND status =0 LIMIT 1"; $query = $this->db->query($mysql); // $num = $query->num_rows(); $provision_list = $query->getResult(); //$provision_list =[]; foreach ($provision_list as $pr) { $this->db->query("UPDATE member_product_refresh SET status = status + 1 WHERE id = " . $pr->id); $subscriptionUId = $pr->subscription_uid; $this->auditProvisionPlans($subscriptionUId); if ($this->refreshBlogProvision($subscriptionUId) == 100) { log_message('critical', "***** ***** scheduleRefresh BLOG Action Started:: () "); } } } private function auditProvisionPlans($subscriptionUid): void { // try { // $sqlP = "SELECT * FROM members_products WHERE uid::text = '$subscriptionUid' "; // $query = $this->db->query($sqlP); // $row = $query->row(); // if (isset($row)) { // echo $row->title; // // // } // } catch (Exception $e) { // echo "Caught exception: " . $e->getMessage() . "\n"; // } finally { // echo "Attempted file operation finished.\n"; // } } private function refreshBlogProvision($subscriptionUId): int { return $this->refreshProvision($subscriptionUId); } private function refreshProvision($subscriptionUId): int { log_message('critical', "***** ***** refreshProvision :: Execute Refresh Provisioning() "); $rsyncPass = "******noNEDD****"; // $remote_composer_path = "chiefsoft@10.0.0.32:/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; // $partMachineLocal = "/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $remote_composer_path = $_ENV['REMOTE_COMPOSER_PATH']; // "chiefsoft@10.0.0.32:/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $partMachineLocal = $_ENV['PATH_MACHINE_LOCAL']; // "/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $ansibleToken = $this->ansibleLogin(); $mysql = "SELECT pp.uid AS prov_uid, p.id AS mpid, p.product_id, pp.id AS plan_id, pp.uid , pp.provision_id, pp.play_file, p.uid AS member_product_uid , p.member_id AS member_id , p.internal_url , p.provision_port, p.provision_status FROM provision_plans pp LEFT JOIN members_products p ON p.id =pp.provision_id WHERE p.uid = '$subscriptionUId' "; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $playFile = $pr->play_file; $planId = $pr->plan_id; $provisionId = $pr->provision_id; $productId = $pr->product_id; $productUid = $pr->member_product_uid; $playbook = $pr->product_id . "_repair.yml"; $provisionUID = $pr->prov_uid; $member_id = $pr->member_id; $internal_url = $pr->internal_url; $provision_port = $pr->provision_port; $members_product_id = $pr->mpid; $this->create_provision_action($member_id, $subscriptionUId, "Rebuilding Provision Started", false); log_message('critical', "Members Product ID ***** " . $pr->mpid . " Provision_Status == " . $pr->provision_status); $this->updateToNow($productUid); // increase count not to repeat $PROVISION_IMAGE_DATA = $this->readProductImageName($productUid); $PROVISION_IMAGE_NAME = $PROVISION_IMAGE_DATA[0]; log_message('critical', "****** PROVISION_IMAGE_NAME ****** " . $PROVISION_IMAGE_NAME); $ansible_host = $productId . "_SERVER"; $ContainerName = $this->generatedContainerName($productId, $pr->mpid); $destinationHomeFolder = $_ENV['DESTINATION_HOME_FOLDER'] . $ContainerName; $composer_template_path_local = $partMachineLocal . $productUid; $composer_template_path_remote = $remote_composer_path . $productUid; $ansible_transport_path = $productUid; // $ContainerName; $CURRENT_IMAGE_REFRESH = $PROVISION_IMAGE_NAME; // "registry.chiefsoft.com/a000001/personal-web-web0002a:latest"; // Remember this is in a CONTAINER so the path follows $this_composer_part_location = "/var/www/html/ANSIBLE/parts/" . $productUid; if (!is_dir($this_composer_part_location)) { mkdir($this_composer_part_location, 0700); } // make sure we compose the docker compose to use $this->prepare_provision_docker_composer( $members_product_id, $provision_port, $productId, $productUid, $member_id, $internal_url ); $this->db->query("UPDATE provision_plans SET updated = now() WHERE id = $planId"); // $this->db->query("UPDATE members_products SET p_file = p_file + 1 WHERE id = $provisionId"); $params = [ "template_id" => (int) $_ENV['ANSIBLE_TEMPLATE_ID'], "debug" => false, "dry_run" => false, "playbook" => $playbook, "environment" => "{ \"WHAT_HOST_IN_USE\":\"$ansible_host\", \"DESTINATION_FOLDER\":\"$destinationHomeFolder\", \"WHAT_PART_LOCAL\":\"$composer_template_path_local\", \"WHAT_PART_REMOTE\":\"$composer_template_path_remote\", \"ANSIBLE_TRANSPORT_PATH\":\"$ansible_transport_path\", \"RSYNC_PASSWORD\":\"$rsyncPass\", \"CONTAINER_NAME\":\"$ContainerName\", \"CURRENT_IMAGE_REFRESH\":\"$CURRENT_IMAGE_REFRESH\" }" ]; log_message('critical', "02- ANSIBLE CALL PARAMETERS ********* " . serialize($params)); $ansibleReturn = $this->ansibleProvision($ansibleToken, $params); log_message('critical', "ANSIBLE RETURN ***** " . $ansibleReturn); if ($ansibleReturn === 200) { log_message('critical', "Calling update_To_Completed ***** " . $ansibleReturn); $this->update_provision_to_completed($productUid); } else { log_message('critical', "Calling WHY PATH update_To_Completed ***** " . $ansibleReturn); $this->update_provision_to_completed($productUid); } $this->create_provision_action($member_id, $subscriptionUId, "Rebuilding Provision Completed", true); } return 100; } private function prepare_provision_docker_composer( $members_product_id, $members_product_port, $product_id, $member_product_uid, $member_id, $internal_url ): void { $public_path = FCPATH; $ansible_folder = str_replace("public/", "ANSIBLE", $public_path); $partMachineLocal = $_ENV['PATH_MACHINE_LOCAL']; $subscriptionId = $members_product_id; $provisionPort = $members_product_port; $productId = $product_id; $provisionUID = $member_product_uid; $memberID = $member_id; $ContainerName = $this->generatedContainerName($productId, $members_product_id); // $productId . str_pad($pr->id, 10, "0", STR_PAD_LEFT); $partFolder = $ansible_folder . "/parts/" . $member_product_uid; /* * may be if the file is already there , we can turn back * */ $destination_composer_path = $ansible_folder . "/parts/" . $provisionUID . "/docker-compose.yml"; $allocatedPort = $provisionPort; $this->updateToNow($provisionUID); if (!is_dir($partFolder)) { mkdir($partFolder, 0700); } // THIS PROVISONING COMPOSERS $composer_template_path = $ansible_folder . "/templates/composers/" . $productId . "/docker-compose.yml"; $composer_template_path_local = $partMachineLocal . $provisionUID; $prov_name = str_replace(".", "_", $internal_url) . ".yml"; $template_file = $ansible_folder . "/templates/" . $productId . ".yml"; //Get the domposer template file $destinationHomeFolder = $_ENV['DESTINATION_HOME_FOLDER'] . $ContainerName; $composer_template_contents = file_get_contents($composer_template_path); // Do the processing $composer_template_contents = $this->prepareTemplateFile($composer_template_contents, $ContainerName, $allocatedPort, $provisionUID, $ansible_folder, $productId, $internal_url, $members_product_id); } private function registerProvision($subscriptionId, $prov_name): void { try { $mysql = "INSERT INTO provision_plans (provision_id,play_file) VALUES($subscriptionId,'$prov_name')"; $query = $this->db->query($mysql); } catch (\Exception $e) { log_message('critical', "***** ***** registerProvision Error:: registerProvision() " . $e->getMessage()); } } private function allocatePortNo(): void { $list_limit = 2; $mysql = "SELECT id, member_id, uid, internal_url,product_id,status,provision_port,updated FROM members_products WHERE provision_port = 0 ORDER BY updated ASC LIMIT " . $list_limit; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $memberID = $pr->member_id; $productId = $pr->product_id; $provisionUID = $pr->uid; $allocated_port = $this->allocatePortNumber($productId); $primary_server = $this->provisionServer($productId); $mysql = "UPDATE members_products SET updated=now(), provision_port=" . $allocated_port . ", primary_server='" . $primary_server . "' WHERE uid::TEXT = '" . $provisionUID . "' AND provision_port = 0"; $query = $this->db->query($mysql); $this->create_provision_action($memberID, $provisionUID, "Allocating Provisioning Ports", false); } //Now let us try fix hanging stuffs $mysql = "SELECT id, member_id, uid, internal_url,product_id,status,provision_port,updated FROM members_products WHERE provision_port > 0 AND status = 6 AND added < now() - INTERVAL '5 minutes' ORDER BY updated ASC LIMIT 1"; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $memberID = $pr->member_id; $productId = $pr->product_id; $provisionUID = $pr->uid; $mysql = "UPDATE members_products SET updated=now(), provision_status=0 WHERE uid::TEXT = '" . $provisionUID . "' AND provision_port > 0"; $query = $this->db->query($mysql); } //SELECT * FROM members_products WHERE status = 6 AND added < now() - INTERVAL '5 minutes' LIMIT 1 } private function allocatePortNumber($productId) { $portF = 0; try { $mysql = "SELECT max(provision_port) AS max_port FROM members_products WHERE product_id = '" . $productId . "'"; $query = $this->db->query($mysql); $maxItem = $query->getResult()[0]->max_port; //var_dump($maxItem); if ($maxItem == 0) { switch ($productId) { case "A000002": $maxItem = 5500; break; case "A000004": $maxItem = 8800; break; case "A000005": $maxItem = 7700; break; case "A000001": $maxItem = 4400; break; case "A000003": $maxItem = 6600; break; case "A000006": $maxItem = 22000; break; } } else { $maxItem = $maxItem + 1; } $portF = $maxItem; } catch (\Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } return $portF; } private function provisionServer($productId) { $primaryServer = ""; switch ($productId) { case "A000001": case "A000002": $primaryServer = $_ENV['DEPLOYMENT_SERVER_1']; break; case "A000003": case "A000004": $primaryServer = $_ENV['DEPLOYMENT_SERVER_2']; break; case "A000005": case "A000006": $primaryServer = $_ENV['DEPLOYMENT_SERVER_3']; break; } return $primaryServer; } /* * [A000001_SERVER] 172.16.4.92 [A000002_SERVER] 172.16.4.92 [A000003_SERVER] 172.16.4.91 [A000004_SERVER] 172.16.4.91 [A000005_SERVER] 172.16.4.95 */ private function updateToNow($provisionUID): void { try { $mysql = "UPDATE members_products SET updated=now(), provision_status=provision_status+1 WHERE uid::TEXT = '" . $provisionUID . "'"; $query = $this->db->query($mysql); } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; log_message('critical', "***** ***** Provision Error:: updateToNow() " . $e->getMessage()); } } private function create_provision_action($memberID, $provisionUID, $actionText, $completedAction = false): void { log_message('critical', "***** ***** Provision :: provisionActions($memberID, $provisionUID,$actionText) "); try { if ($completedAction) { $percent_completed = 100; } else { $percent_completed = 10; $mysql_find = "SELECT * FROM provision_actions WHERE product_uid = '$provisionUID' ORDER BY id DESC limit 1"; $query_find = $this->db->query($mysql_find); $row = $query_find->getResult('array'); if (count($row) > 0) { $percent_completed = (int) $row[0]['percent_completed']; $percent_completed = $percent_completed + 10; } } if ($percent_completed > 100) $percent_completed = 100; $mysql = "INSERT INTO provision_actions (member_id,product_uid,action ,percent_completed) VALUES ($memberID,'$provisionUID','$actionText', $percent_completed)"; log_message('info', "***** ***** Provision :: provisionActions(QUERY) :: " . $mysql); $query = $this->db->query($mysql); // TELL THE SOCKET TO REFRESH PAGE $data["product_uid"] = $provisionUID; $data["provision_action"] = urlencode($actionText); $SOCKET_SERVER_LOCATION = $_ENV['SOCKET_SERVER_LOCATION']; log_message('info', "***** ***** Provision :: Action To :: " . $SOCKET_SERVER_LOCATION . '/broadcast/provisioning'); $this->APIcall("GET", $SOCKET_SERVER_LOCATION . '/broadcast/provisioning', $data); sleep(10); } catch (\Exception $e) { log_message('critical', "***** ***** Provision Error:: provisionActions() " . $e->getMessage()); } } public function releaseProvision(): int { log_message('info', "***** ***** ReleaseProvision :: Execute Actual Provisioning() "); $PROCESS_LIMIT = 2; $rsyncPass = "******noNEDD****"; // $remote_composer_path = "chiefsoft@10.0.0.32:/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; // $partMachineLocal = "/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $remote_composer_path = $_ENV['REMOTE_COMPOSER_PATH']; // "chiefsoft@10.0.0.32:/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $partMachineLocal = $_ENV['PATH_MACHINE_LOCAL']; // "/home/chiefsoft/MermsProvision/ANSIBLE/parts/"; $ansibleToken = $this->ansibleLogin(); $mysql = "SELECT pp.uid AS prov_uid, p.id AS mpid, p.product_id, pp.id AS plan_id, pp.uid , pp.provision_id, pp.play_file, p.uid AS member_product_uid , p.member_id AS member_id , p.internal_url , p.provision_port, p.provision_status FROM provision_plans pp LEFT JOIN members_products p ON p.id =pp.provision_id WHERE p.provision_status = 1 ORDER BY pp.updated ASC LIMIT " . $PROCESS_LIMIT; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $playFile = $pr->play_file; $planId = $pr->plan_id; $provisionId = $pr->provision_id; $productId = $pr->product_id; $productUid = $pr->member_product_uid; $playbook = $pr->product_id . ".yml"; $provisionUID = $pr->prov_uid; $member_id = $pr->member_id; $internal_url = $pr->internal_url; $provision_port = $pr->provision_port; $members_product_id = $pr->mpid; log_message('info', "Members Product ID ***** " . $pr->mpid . " Provision_Status == " . $pr->provision_status); $this->updateToNow($productUid); // increase count not to repeat $ansible_host = $productId . "_SERVER"; $ContainerName = $this->generatedContainerName($productId, $pr->mpid); //$productId ."-SVR-". str_pad($pr->mpid, 10, "0", STR_PAD_LEFT); //$destinationHomeFolder = "/home/chiefsoft/SITES/" . $ContainerName; $destinationHomeFolder = $_ENV['DESTINATION_HOME_FOLDER'] . $ContainerName; // $composer_template_path_local = $partMachineLocal . $provisionUID; // $composer_template_path_remote = $remote_composer_path . $provisionUID; $composer_template_path_local = $partMachineLocal . $productUid; $composer_template_path_remote = $remote_composer_path . $productUid; // $ansible_transport_path = $pr->provision_uid; // $ContainerName; $ansible_transport_path = $productUid; // $ContainerName; // let us make sure all we promise are availale //"WHAT_PART_LOCAL // Remember this is in a CONTAINER so the path follows $this_composer_part_location = "/var/www/html/ANSIBLE/parts/" . $productUid; if (!is_dir($this_composer_part_location)) { mkdir($this_composer_part_location, 0700); } // make sure we compose the docker compose to use $this->prepare_provision_docker_composer( $members_product_id, $provision_port, $productId, $productUid, $member_id, $internal_url ); $this->db->query("UPDATE provision_plans SET updated = now() WHERE id = $planId"); $this->db->query("UPDATE members_products SET p_file = p_file + 1 WHERE id = $provisionId"); $params = [ "template_id" => (int) $_ENV['ANSIBLE_TEMPLATE_ID'], "debug" => false, "dry_run" => false, "playbook" => $playbook, "environment" => "{ \"WHAT_HOST_IN_USE\":\"$ansible_host\", \"DESTINATION_FOLDER\":\"$destinationHomeFolder\", \"WHAT_PART_LOCAL\":\"$composer_template_path_local\", \"WHAT_PART_REMOTE\":\"$composer_template_path_remote\", \"ANSIBLE_TRANSPORT_PATH\":\"$ansible_transport_path\", \"RSYNC_PASSWORD\":\"$rsyncPass\", \"CONTAINER_NAME\":\"$ContainerName\" }" ]; log_message('critical', "01- ANSIBLE CALL PARAMETERS ********* " . serialize($params)); $ansibleReturn = $this->ansibleProvision($ansibleToken, $params); log_message('critical', "ANSIBLE RETURN ***** " . $ansibleReturn); if ($ansibleReturn === 200) { log_message('critical', "Calling update_To_Completed ***** " . $ansibleReturn); $this->update_provision_to_completed($productUid); } else { log_message('critical', "Calling WHY PATH update_To_Completed ***** " . $ansibleReturn); $this->update_provision_to_completed($productUid); } $this->create_provision_action($member_id, $productUid, "Provisioning Completed", true); } return 0; } private function update_provision_to_completed($provisionUID): void { log_message('critical', "update_To_Completed ******** ***** " . $provisionUID); try { $mysql = "UPDATE members_products SET updated=now(), provision_status=provision_status+1 , status = 7 WHERE status = 6 AND uid::TEXT = '" . $provisionUID . "'"; $query = $this->db->query($mysql); } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; log_message('critical', "***** ***** Provision Error:: updateToCompleted() " . $e->getMessage()); } } public function directProvision(): int { $mysql = "SELECT id AS plan_id, uid, provision_id, play_file from provision_plans ORDER BY updated ASC LIMIT 1 "; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $playFile = $pr->play_file; $planId = $pr->plan_id; $provisionId = $pr->provision_id; $this->db->query("UPDATE provision_plans SET updated = now() WHERE id = $planId"); $this->db->query("UPDATE members_products SET p_file = p_file + 1 WHERE id = $provisionId"); //$this->runAnsibleShell($playFile); try { log_message('critical', "***** ***** Provision :: runAnsibleShell($playFile) "); $shellCommand = "ansible-playbook --vault-password-file /var/www/html/ANSIBLE/secrets.pass --key-file ~/.ssh/ansible_worker -i /var/www/html/ANSIBLE/inventory /var/www/html/ANSIBLE/$playFile"; log_message('critical', $shellCommand); $output = shell_exec($shellCommand); log_message('critical', "***** ***** Provision :: runAnsibleShell(output) AFTER SHELL RUN " . $output); } catch (\Exception $e) { log_message('critical', "***** ***** Provision Error:: runAnsibleShell() " . $e->getMessage()); } } return 0; } public function demo(): string { $PROJECT_ID = 8; $result = "Unhandled exception"; $base_url = "http://172.16.4.90:3000"; $cookies = tempnam('/tmp', 'cookie.txt'); # 1. Login $url = $base_url . "/api/auth/login"; $ch = curl_init($url); # Setup request to send json via POST. $payload = json_encode(array("auth" => "admin", "password" => "may12002")); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); # Return response instead of printing. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # Fetch the headers, not the body content: //curl_setopt($ch, CURLOPT_HEADER, true); // we want headers //curl_setopt($ch, CURLOPT_NOBODY, true); // we don't need body # Cookie jar curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); # Send request. $result = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $result = 'HTTP code: ' . $httpcode; curl_close($ch); if ($httpcode != "204") { return "Login failed! $result"; } # 2. Get token $url = $base_url . "/api/user/tokens"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); $res = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $token = null; $arr = json_decode($res, true); foreach ($arr as $item) { if ($item["expired"] === false) { $token = $item["id"]; break; } } $result = "Found token: $token"; # 3. Lauch task $PROJECT_ID = 7; $url = $base_url . "/api/project/$PROJECT_ID/tasks"; $headers = [ 'Content-Type:application/json', 'Accept: application/json', 'Authorization: Bearer ' . $token ]; $ch = curl_init($url); $payload = json_encode(array("template_id" => 1, "debug" => false, "dry_run" => false, "playbook" => "first-playbook.yml", "environment" => "{}")); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $result .= "\n" . 'Launch task HTTP code: ' . $httpcode; curl_close($ch); # 4. Get tasks $url = $base_url . "/api/project/$PROJECT_ID/tasks"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $result .= "\n" . 'Get tasks HTTP code: ' . $httpcode; curl_close($ch); ob_start(); var_dump($headers); var_dump($res); $result .= "\n" . ob_get_clean(); # Print response. return "
$result
"; } public function configureURL() { log_message('critical', "***** ***** Configure URL :: Set up URL access for product "); $limit = 1; $mysql = "SELECT id, uid, internal_url,primary_server,provision_port,url_status,member_id FROM members_products WHERE url_status = 0 LIMIT $limit"; $query = $this->db->query($mysql); $provision_list = $query->getResult(); foreach ($provision_list as $pr) { $mbId = $pr->id; $provisionURL = $pr->internal_url; $provisionServer = $pr->primary_server; $provisionPort = $pr->provision_port; $provisionUID = $pr->uid; $memberID = $pr->member_id; log_message('critical', "***** ***** Configure URL Start ::: $provisionURL == $provisionServer:$provisionPort "); // Here call haproxy actions list($res, $message) = $this->configureHaproxyURL($provisionURL, $provisionServer, $provisionPort); // TODO: Check $res for errors $mysql_close = "UPDATE members_products SET url_status = url_status + 1 WHERE id = $mbId "; $this->db->query($mysql_close); log_message('critical', "***** ***** Conclude if all Okay => $mysql_close "); $this->create_provision_action($memberID, $provisionUID, "Automatic URL Setup Started", false); } } public function haproxy(): string { // $limit = 1; // $mysql = "SELECT // internal_url, // provision_port, // product_id, // url_status // FROM members_products // WHERE url_status = 0 LIMIT $limit"; // $query = $this->db->query($mysql); // $provision_list = $query->getResult(); // foreach ($provision_list as $pr) { // $provisionURL = $pr->internal_url; // $productId = $pr->product_id; // $provisionPort = $pr->provision_port; // $provisionUID = $pr->uid; // // // // log_message('critical', "***** ***** Configure URL $provisionURL to Point to ::: $provisionServer:$provisionPort "); // // } list($res, $message) = $this->configureHaproxyURL("23607.devprov.mermsemr.com", "172.16.4.91", "6603"); var_dump($message); log_message('critical', "Message => '" . $message . "'"); return "Message:
" . $message; } public function QuickFix() { return $this->configureHaproxyURL('sanyaameye.pers.mermsemr.com', '10.13.1.28', '4400'); } public function configureHaproxyURL($provisionURL, $provisionServer, $provisionPort) { $message = ""; $base_url = $_ENV['HAPROXY_SERVER_URL']; //'http://172.16.4.99:5555'; $username = $_ENV['HAPROXY_SERVER_USER']; //'admin'; $password = $_ENV['HAPROXY_SERVER_PASS']; //'Hapr0xy001'; log_message('critical', "provisionURL => $provisionURL"); log_message('critical', "provisionServer => $provisionServer"); log_message('critical', "provisionPort => $provisionPort"); $status_code = []; // 200 list($status_code[0], $cfgver) = $this->getHaProxyCfgVer($base_url, $username, $password); $cfgver0 = trim($cfgver); // Add backend /* # Add backend # https://www.haproxy.com/documentation/dataplaneapi/community/?v=v3#post-/services/haproxy/configuration/backends curl -XPOST --user admin:Hapr0xy001 \ -H 'Content-Type: application/json' -H 'Accept: application/json' \ -d '{ "name": "backend'$CFGVER'", "mode": "http", "http_connection_mode": "httpclose", "forwardfor": { "enabled": "enabled" }, "compression": { "algorithms": ["gzip"], "types": ["text/html", "text/plain", "text/css", "text/javascript"] } }' \ "http://172.16.4.99:5555/v3/services/haproxy/configuration/backends?version=$CFGVER" > backend.txt */ $backend = "backend" . $cfgver0; $data = [ "name" => $backend, "mode" => "http", "http_connection_mode" => "httpclose", "forwardfor" => [ "enabled" => "enabled" ], "compression" => [ "algorithms" => ["gzip"], "types" => ["text/html", "text/plain", "text/css", "text/javascript"] ] ]; $uri = '/v3/services/haproxy/configuration/backends?version=' . $cfgver0; // 202 list($status_code[1], $result) = $this->getHaProxyPost($base_url, $username, $password, $uri, $data); // TODO: check the status code // 200 list($status_code[2], $cfgver) = $this->getHaProxyCfgVer($base_url, $username, $password); $cfgver = trim($cfgver); // Add Server /* #https://www.haproxy.com/documentation/dataplaneapi/community/?v=v3#post-/services/haproxy/configuration/backends/-parent_name-/servers curl -XPOST --user admin:Hapr0xy001 \ -H 'Content-Type: application/json' -H 'Accept: application/json' \ -d '{ "name": "server'$CFGVER'", "address": "172.16.4.92", "port": 4401, "check": "enabled", "health_check_port": 4401 }' \ "http://172.16.4.99:5555/v3//services/haproxy/configuration/backends/$BACKEND/servers?version=$CFGVER" > server.txt */ # test => "server4" $server = "server" . $cfgver0; $data = [ "name" => $server, "address" => $provisionServer, "port" => (int) $provisionPort, "check" => "enabled", "health_check_port" => (int) $provisionPort ]; $uri = '/v3/services/haproxy/configuration/backends/' . $backend . '/servers?version=' . $cfgver; // 202 list($status_code[3], $result) = $this->getHaProxyPost($base_url, $username, $password, $uri, $data); // TODO: check the status code // 200 list($status_code[4], $cfgver) = $this->getHaProxyCfgVer($base_url, $username, $password); $cfgver = trim($cfgver); // Add a new ACL to "http" frontend /* # https://www.haproxy.com/documentation/dataplaneapi/community/?v=v3#post-/services/haproxy/configuration/frontends/-parent_name-/acls/-index- curl -X POST --user admin:Hapr0xy001 \ -H 'Content-Type: application/json' -H 'Accept: application/json' \ -d '{ "acl_name": "acl'$CFGVER'", "criterion": "req.hdr(Host)", "value": "23233.devprov.mermsemr.com" }' \ "http://172.16.4.99:5555/v3/services/haproxy/configuration/frontends/http/acls/0?version=$CFGVER" */ $acl = "acl" . $cfgver0; $data = [ "acl_name" => $acl, "criterion" => "req.hdr(Host)", "value" => $provisionURL ]; $uri = '/v3/services/haproxy/configuration/frontends/http/acls/0?version=' . $cfgver; // 202 list($status_code[5], $result) = $this->getHaProxyPost($base_url, $username, $password, $uri, $data); // TODO: check the status code // 200 list($status_code[6], $cfgver) = $this->getHaProxyCfgVer($base_url, $username, $password); $cfgver = trim($cfgver); // Add a new Backend Switching Rule to "http" frontend for "use_backend" /* # https://www.haproxy.com/documentation/dataplaneapi/community/?v=v3#post-/services/haproxy/configuration/frontends/-parent_name-/backend_switching_rules/-index- curl -X POST --user admin:Hapr0xy001 \ -H 'Content-Type: application/json' -H 'Accept: application/json' \ -d '{ "name": "'$BACKEND'", "cond": "if", "cond_test": "'$ACL'" }' \ "http://172.16.4.99:5555/v3/services/haproxy/configuration/frontends/http/backend_switching_rules/0?version=$CFGVER" > use_backend.txt */ $data = [ "name" => $backend, "cond" => "if", "cond_test" => $acl ]; $uri = '/v3/services/haproxy/configuration/frontends/http/backend_switching_rules/0?version=' . $cfgver; // 202 list($status_code[7], $result) = $this->getHaProxyPost($base_url, $username, $password, $uri, $data); // TODO: check the status code // 200 list($status_code[8], $cfgver) = $this->getHaProxyCfgVer($base_url, $username, $password); $cfgver = trim($cfgver); $codes = ""; foreach ($status_code as $i => $code) { $codes .= "\n$i => $code"; } return [$status_code[7], "
FIRST CFGVER=$cfgver0\n\n--- CODES: ----$codes\n\nLAST CFGVER=$cfgver
"]; } private function getHaproxyPost($base_url, $username, $password, $uri, $data) { $url = $base_url . $uri; $payload = json_encode($data); $headers = array( 'Content-Type:application/json', 'Authorization: Basic ' . base64_encode("$username:$password") // <--- ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout after 30 seconds curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // Debug //curl_setopt($ch, CURLOPT_VERBOSE, true); //$streamVerboseHandle = fopen('php://temp', 'w+'); //curl_setopt($ch, CURLOPT_STDERR, $streamVerboseHandle); // End Debug $result = curl_exec($ch); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code if ($result === FALSE) { $result = sprintf("cUrl error (#%d): %s
\n", curl_errno($ch), htmlspecialchars(curl_error($ch))); } // Debug //rewind($streamVerboseHandle); //$verboseLog = stream_get_contents($streamVerboseHandle); //$result .= "\ncUrl verbose information:\n
" . htmlspecialchars($verboseLog) . "
\n"; //$result .= "
$payload
\n"; // End Debug curl_close($ch); return [$status_code, $result]; } private function getHaproxyGet($base_url, $username, $password, $uri) { $url = $base_url . $uri; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout after 30 seconds curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); $result = curl_exec($ch); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code curl_close($ch); return [$status_code, $result]; } private function getHaproxyCfgVer($base_url, $username, $password) { return $this->getHaproxyGet($base_url, $username, $password, '/v3/services/haproxy/configuration/version'); } }