Files
MermsProvision/app/Controllers/Provision.php
T
CHIEFSOFT\ameye 8aac4b1df5 $productUid
2025-07-16 18:03:28 -04:00

766 lines
32 KiB
PHP

<?php
namespace App\Controllers;
class Provision extends BaseController
{
public function prepareProvision(): string
{
$this->allocatePortNo(); // allocte port for the conyainer use
$this->prepareDataBase(); // allocte port for the conyainer use
$this->updateProvision();
return 0;
}
private function prepareDataBase():string
{
$servername = "172.16.4.96:3307";
$database = "wordpress";
$username = "root";
$password = "may12002!";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $database);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "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')
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);
// $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);
$dbName = $ContainerName;
// Create database
$sql = "CREATE DATABASE $dbName";
if ($conn->query($sql) === TRUE) {
// echo "Database created successfully";
log_message('critical', "***** ***** 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 . "'";
$result = mysqli_query($conn, $sql);
$sql = "GRANT SELECT , INSERT , UPDATE , DELETE ON " . $dbName . " . * TO '" . $dbName . "'@'localhost' IDENTIFIED BY '" . $provisionUID . "'";
$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;
}
}
// Check connection
mysqli_close($conn);
return '';
}
private function generatedContainerName($productId, $provID){
return $productId ."-SVR-" . 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;
$memberID = $pr->member_id;
$ContainerName = $this->generatedContainerName($productId, $pr->id ); // $productId . str_pad($pr->id, 10, "0", STR_PAD_LEFT);
$partFolder = $ansible_folder . "/parts/" . $provisionUID;
$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(".", "_", $pr->internal_url) . ".yml";
$template_file = $ansible_folder . "/templates/" . $pr->product_id . ".yml";
//Get the domposer template file
$composer_template_contents = file_get_contents($composer_template_path);
// Do the processing
$composer_template_contents = str_replace("WHAT_CONTAINER_NAME", $ContainerName, $composer_template_contents);
//$destinationHomeFolder = "/home/chiefsoft/SITES/" . $ContainerName;
$destinationHomeFolder =$_ENV['DESTINATION_HOME_FOLDER'] . $ContainerName;
$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_PASS", $provisionUID, $composer_template_contents);
$composer_template_contents = str_replace("CNT_DB_DATA", '172.16.4.96:3307', $composer_template_contents);
//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);
// 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->provisionActions($memberID, $provisionUID, "Auto Configuration Started");
}
return view('welcome_message');
}
private function registerProvision($subscriptionId,$prov_name){
/*
CREATE TABLE provision_plans (
id SERIAL,
uid uuid DEFAULT uuid_generate_v4(),
provision_id INT REFERENCES members_products(id),
play_file VARCHAR(100)UNIQUE NOT NULL,
msg VARCHAR(100) ,
added timestamp without time zone DEFAULT now(),
updated timestamp without time zone DEFAULT now()
);
ALTER TABLE ONLY provision_plans
ADD CONSTRAINT provision_plans_id_key UNIQUE (id);
*/
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());
}
return 0;
}
private function allocatePortNo(){
$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->provisionActions($memberID, $provisionUID, "Allocating Provisioning Ports");
}
}
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;
}
}
else{
$maxItem = $maxItem+1;
}
$portF = $maxItem;
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
return $portF;
}
private function provisionServer($productId){
switch ($productId) {
case "A000001":
case "A000002":
$primaryServer = "172.16.4.92";
break;
case "A000003":
case "A000004":
$primaryServer = "172.16.4.91";
break;
case "A000005":
$primaryServer = "172.16.4.95";
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){
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 provisionActions($memberID, $provisionUID,$actionText){
log_message('critical', "***** ***** Provision :: provisionActions($memberID, $provisionUID,$actionText) ");
try {
$mysql = "INSERT INTO provision_actions (member_id,product_uid,action) VALUES ($memberID,'$provisionUID', '$actionText')";
log_message('critical', "***** ***** Provision :: provisionActions(QUERY) :: ".$mysql);
$query = $this->db->query($mysql);
// TELL THE SOCKET TO REFRESH PAGE
$data["product_uid"] = $provisionUID;
$SOCKET_SERVER_LOCATION = $_ENV['SOCKET_SERVER_LOCATION'];
$this->APIcall("GET", $SOCKET_SERVER_LOCATION .'/broadcast/provisionings', $data);
} catch ( \Exception $e) {
// echo 'Caught exception: ', $e->getMessage(), "\n";
log_message('critical', "***** ***** Provision Error:: provisionActions() ".$e->getMessage());
}
return 0;
}
public function releaseProvision(){
$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
FROM provision_plans pp
LEFT JOIN members_products p ON p.id =pp.provision_id
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;
log_message('critical', "Members Product ID ***** ".$pr->mpid);
$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;
$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"=> 2,
"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\"
}"
];
$this->ansibleProvision($ansibleToken, $params);
}
return 0;
}
// public function runAnsibleShell($provisionFile){
// try{
// log_message('critical', "***** ***** Provision :: runAnsibleShell($provisionFile) ");
// $shellCommand ="/var/www/html/ANSIBLE/auto_play.sh A000001.yml OLU AMEYE "; ///var/www/html/ANSIBLE/$provisionFile";
// log_message('critical', $shellCommand);
// $output = shell_exec($shellCommand );
// log_message('critical', "***** ***** Provision :: runAnsibleShell(output) AFTER SHELL RUN ".serialize($output));
//
//// $shellCommand ="ansible-playbook --vault-password-file /var/www/html/ANSIBLE/secrets.pass --key-file ~/.ssh/ansible_worker -i /var/www/html/ANSIBLE/inventory $provisionFile";
//// log_message('critical', $shellCommand);
////
//// $output = shell_exec($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 directProvision(){
$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 "<pre>$result</pre>";
}
public function configureURL(){
$limit = 1;
$mysql = "SELECT uid, internal_url,primary_server,provision_port,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;
$provisionServer = $pr->primary_server;
$provisionPort = $pr->provision_port;
$provisionUID = $pr->uid;
log_message('critical', "***** ***** Configure URL $provisionURL to Point to ::: $provisionServer:$provisionPort ");
// Here call haproxy actions
list ($res, $message) = $this->configureHaproxyURL($provisionURL,$provisionServer,$provisionPort);
// TODO: Check $res for errors
$mysql_close = "UPDATE members_products WHERE SET url_status = 1 WHERE uid:;text = '$provisionUID' ";
log_message('critical', "***** ***** Conclude if all Okay => $mysql_close ");
}
}
public function haproxy():string {
list ($res, $message) = $this->configureHaproxyURL("23607.devprov.mermsemr.com","172.16.4.91","6603");
var_dump($message);
log_message('critical',"Message => '".$message."'");
return "Message:<br/>".$message;
}
public function configureHaproxyURL($provisionURL, $provisionServer, $provisionPort) {
$message = "";
$base_url = 'http://172.16.4.99:5555';
$username = 'admin';
$password = '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],"<pre>FIRST CFGVER=$cfgver0\n\n--- CODES: ----$codes\n\nLAST CFGVER=$cfgver</pre>"];
}
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<br>\n", curl_errno($ch), htmlspecialchars(curl_error($ch)));
}
// Debug
//rewind($streamVerboseHandle);
//$verboseLog = stream_get_contents($streamVerboseHandle);
//$result .= "\ncUrl verbose information:\n<pre>" . htmlspecialchars($verboseLog) . "</pre>\n";
//$result .= "<pre>$payload</pre>\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');
}
}