Thursday 9 July 2015

Simple web app to start non-prod applications that are in stopped state

A simple pattern in cloud is to stop non-production instances at night and weekend. This can be done with by tagging every instance with Costsavings tag, here is example::
Sun:Mon 07.00 23:00:Tue 07.00 23.00:Wed 07.00 23.00:Thu 07.00 23.00:Fri 07.00 23.00:Sat:31.12.2100:JiraDev

This tag specifies when the instance should be started/stopped and a Lambda scheduler will stop and start instances at required times. 

Yet when an application is stopped a developer may wish to use this application. For this purpose a the following PHP web application can be used to start stopped applications:

Every minute an automated script produces list of applications and their status into file app.csv:
app1:app1-uat:i-12345678:0:stopped:start
app2:app2-web,web2-db:i-12345601,i-12345602:120,0:stopped:start
app3:app3-uat:i-12345603:0:running:
app4:app4-web-uat,app4-app-uat,app4-db-uat:i-12345604,i-12345605,i-12345606:120,120,0:stopped:start
app5:app5-web-uat,app5-app-uat,app5-db-uat:i-12345607,i-12345608,i-12345609:120,120,0:stopped:start
zoranapp:app1-uat:i-0011b431b3bcccdaf:0:stopped:start

Script to produce file:

ec2 | tee ec2.`date +'%H.%M'`.out | cut -d ',' -f1-4,7,33,35-36 | grep -iv ',Prod$' | grep -iv ',null$' | while read line
do
account=`echo $line | cut -d',' -f1`
instance=`echo $line | cut -d',' -f2`
status=`echo $line | cut -d',' -f5`
name=`echo $line | cut -d',' -f6`
app=`echo $line | cut -d',' -f7`
echo "$account,$app,$name,$instance,$status"
done | sort > ec2.tmp

for app in `cat ec2.tmp | cut -d',' -f2 | sort | uniq`
do
   account=`grep "^$app," ec2.tmp | head -1 | cut -d',' -f1`
   name=`grep "^$app," ec2.tmp | cut -d',' -f3 | tr '\n' ','`
   instance=`grep "^$app," ec2.tmp | cut -d',' -f4 | tr '\n' ','`
   state=`grep "^$app," ec2.tmp | cut -d',' -f5 | tr '\n' ','`
   echo "$account:$app:$name:$instance:$status"
done > app.csv   


dashboard.php - produce a dashboard with status for all applications:
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>dashboard.php</title>
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
.row {
  background: #f8f9fa;
  margin-top: 20px;
}

.col {
  border: solid 1px #6c757d;
  padding: 10px;
}
</style>
</head>
<body>
 <h1>Applications Dashboard</h1>
 <div>
 <?php
  ini_set('display_startup_errors', 1);
  ini_set('display_errors', 1);
  error_reporting(-1);

  print <<< HERE
  <table class="table table-striped">
  <thead>
  <tr>
   <th>Application</th>
   <th>Instance Name(s)</th>
   <th>Instance ID(s)</th>
   <th>Status</th>
   <th>Action</th>
  </tr>
  </thead>
  HERE;

  $data = file("app.csv");
  // var_dump($data);
  foreach ($data as $line){
   $lineArray = explode(":", $line);
   list($app, $name, $instance, $delay, $status, $action) = $lineArray;
   print <<< HERE
   <tr>
   <td>$app</td>
   <td>$name</td>
   <td>$instance</td>
   HERE;

   $id=$app;
   $salt="TOPSECRET";
   $encrypted_id = base64_encode($id . $salt);
   if ($status == 'stopped') { print '<td><p style="color:red;">' . "$status</p></td>"; } else {  print '<td><p style="color:green;">' . "$status</p></td>"; }
   if ($status == 'stopped') { print '<td>Click <a href="http://10.21.61.73/start.php?id=' . "$encrypted_id" . '">here</a> to start application instances</td>'; } else { print '<td></td>'; }
   print <<< HERE
   </td>
   </tr>
   HERE;
  } // end foreach
  //print the bottom of the table
  print "</table>\n";
 ?>
 </div>
</body>
</html>

start.php - start the selected application: 
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>paramaters.php</title>
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
.row {
  background: #f8f9fa;
  margin-top: 20px;
}

.col {
  border: solid 1px #6c757d;
  padding: 10px;
}
</style>
</head>
<body>
 <h1>Starting Application</h1>
 <div>
 <?php
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(-1);

echo '<PRE>';
// echo "<br><br>id = " .  $_GET["id"] . "<br><br>";
$decrypted_id_raw = base64_decode($_GET["id"]);
$salt="TOPSECRET";
$decrypted_id = preg_replace(sprintf('/%s/', $salt), '', $decrypted_id_raw);
// echo "<br><br>id = " .  $decrypted_id . "<br><br>";

require 'vendor/autoload.php';
use Aws\Ec2\Ec2Client;

$ec2Client = new Aws\Ec2\Ec2Client([
    'region' => 'ap-southeast-2',
    'version' => 'latest',
    'profile' => 'default'
]);

$line = exec("grep $decrypted_id app.csv");
$lineArray = explode(":", $line);
list($app, $name, $instance, $delay, $status, $action) = $lineArray;
echo "Application: $app\nName(s): $name\nInstance(s): $instance\n\nResults:\n";
$instanceIds = explode(",", $instance);
$result = $ec2Client->startInstances(array('InstanceIds' => $instanceIds));
// var_dump($result);
echo($result);

echo '</body>
</html>';
?>

No comments:

Post a Comment