Model Source Code

Note: For a detailed annotation of Dockerfile and source code, refer to the files in the preceding folders: MVP_App and MVP_Docker

MyContainerCl-py

#!/usr/bin/python3
import os
import sys
from flask import Flask, render_template
from flask_bower import Bower
from flask import request
import json
from flask import jsonify
from pymongo import MongoClient, DESCENDING
from sys import stdout
from sys import stdin
from time import sleep
client = MongoClient("mongodb://localhost:27017")
db = client.portalDB
messages = []
prefix = "null"
neighbor = "null"
aspath = "null"
nexthop = "null"
localpref = "null"
opnotes = "null"
app = Flask(__name__)
@app.route("/")
def main():
    return render_template('sandbox5.html')

@app.route("/AnnouncePrefix",methods=['POST'])
def AnnouncePrefix():
    try:
        json_data = request.json['info']
        prefix = json_data['prefix']
        neighbor = json_data['neighbor']
        nexthop = json_data['nexthop']
        aspath = json_data['aspath']
        localpref = json_data['localpref']
        opnotes = json_data['opnotes']
        db.prefixinfo2.insert_one({
            'prefix':prefix,'neighbor':neighbor,'nexthop':nexthop,'aspath':aspath,'localpref':localpref, 'opnotes':opnotes
            })
        route_adv = "announce route " + " " + prefix + " next-hop" + " " + nexthop
        stdout.write( route_adv + '\n')
        stdout.flush()
        sleep(1)
        return jsonify(status='OK',message='inserted successfully',result=prefix)

    except Exception as e:
        return jsonify(status='ERROR',message=str(e))
@app.route("/RemovePrefix",methods=['POST'])
def RemovePrefix():
    try:
         json_data = request.json['info']
         prefix = json_data['prefix']
         db.prefixinfo2.delete_many({'prefix':prefix})
#         return jsonify(status='OK',message='deleted successfully',result= DeleteResult)
#    except Exception,e:
#        return jsonify(status='ERROR',message=str(e)) 
         prefixcount = db.prefixinfo2.count({'prefix':prefix})
         route_withdraw = "withdraw route " + " " + prefix 
         stdout.write( route_withdraw + '\n')
         stdout.flush()
         sleep(.1)
         return jsonify(status='OK',message='Prefixes Remaining',result=prefixcount)
    except Exception as e:
        return jsonify(status='ERROR',message=str(e))
@app.route("/SearchPrefix",methods=['POST'])
def SearchPrefix():
    try:
        json_data = request.json['info']
        prefix = json_data['prefix']
        prefixcount = db.prefixinfo2.count({'prefix':prefix})
        return jsonify(status='OK',message='found successfully',result=prefixcount)
    except Exception as e:
        return jsonify(status='ERROR',message=str(e))
@app.route("/repush",methods=['POST'])
def repush():
      try:
         prefix_adv = 0
         message = " "
         cursorPos= db.prefixinfo2.find()
         for record in cursorPos:
             next_entry = "announce route " + " " + record['prefix'] + " next-hop" + " " + record['nexthop']
             stdout.write( next_entry + '\n')
             prefix_adv  = prefix_adv+1    
             stdout.flush()
             sleep(.1)
         return jsonify(pusherr='false',pushed="true",message=message,result=prefix_adv)
      except Exception as e:
        return jsonify(pusherr='true',pushed="true",stat='ERROR at some place in the prefix DB push:',msg=str(e))    


if __name__ == "__main__":
    app.run()


sandbox5.html


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Black Hole Route Injection</title>

    <!-- Bootstrap -->
    <!link href="static/js/bootstrap.tmp.css" rel="stylesheet">
    <link href="http://HOST-REF:30100/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <link href="http://HOST-REF:30100/bower_components/bootstrap-css/css/bootstrap-theme.min.css" rel="stylesheet">
    <!script type="text/javascript" src="localhost:8081/bower_components/angular/angular.js"></script>
    <!script src="https://rawgit.com/CautemocSg/ng-ip-address/master/ngIpAddress.min.js"></script>
</head>

<body>
    <div ng-app="myApp" ng-controller="HomeCtrl">
        <form name="SearchForm">

            <div ng-if="PhaseOne">
                <div class="container">
                    <div class="header">
                        <nav>
                            <ul class="nav nav-pills pull-right">
                            </ul>
                        </nav>
                        <h3 align="center">Route Black-Hole Portal</h3>
                    </div>
                    <div class="jumbotron">
                        <h3 align="left">Re-push all B-H prefixes? Or search for a B-H prefix in the Data Base?</h3>
                        <button class="w3-btn w3-large w3-blue" ng-click="Repush()">Repush ?</button>
                        <button class="w3-btn w3-large w3-blue" ng-click="DBaseSearch()">Database Search ?</button>
                    </div>
                </div>
            </div>
            <div ng-if="repush">
                <div>
                    <div class="container">
                        <div class="header">
                            <nav>
                                <ul class="nav nav-pills pull-right">
                                </ul>
                            </nav>                                                  
                        </div>
                        <div class="jumbotron">
                            <h3 align="left">Push results </h3>
                            <span ng-show="repushed == 'false'">
                                <button ng-click="Repush()">Repush all Prefixes</button> </span>
                            <div ng-if="PushedErr == 'true'">
                                There were problems:likely DB content/access issues                                
                                <label for="txtmessage" class="control-label">Error Message:</label>
                                <input type="text" ng-readonly="ReadOnly" class="form-control" ng-model="message" id="txtmessage">
                                <input type="button" value="Refresh the Page For New Request ?" onClick="window.location.reload()">                                
                            </div>  
                            <div ng-if="PushedErr == 'false'">
                                <label for="txtPrefixes" class="control-label">Prefixes Copied:</label>
                               <input type="text" ng-readonly="ReadOnly" class="form-control" ng-model="PrefixCopied" id="txtPrefixes">
                                <input type="button" value="Refresh the Page For New Request ?" onClick="window.location.reload()">
                            </div> 
                        </div>
                    </div>
                </div>
            </div>
            <div ng-if="DBSearched && buttonpressed == false">
                <div class="container">
                    <div class="header">
                        <nav>
                            <ul class="nav nav-pills pull-right">
                            </ul>
                        </nav>
                        <h3 align="center">Route Black-Hole Portal</h3>
                    </div>
                    <div class="jumbotron">
                        <h3 align="center">Data base Search </h3>
                        <div>
                            <fieldset>
                                <legend>Enter Address for Search</legend>
                                <label>IP Address</label>
                                <input type="text" name="SearchInput1" ng-model="$parent.ipAddress1" ng-ip-address />
                                <span ng-if="SearchForm.SearchInput1.$invalid">Invalid</span>
                                <div>
                                    <span ng-if="SearchForm.SearchInput1.$dirty && SearchForm.SearchInput1.$valid">
                                    Valid
                                    <button ng-click="selectentry()">Select</button></span>
                                </div>
                            </fieldset>
                        </div>
                    </div>
                </div>
            </div>
            <div>
                <div ng-if="DBSearched && buttonpressed">
                    <div class="container">
                        <div class="header">
                            <nav>
                                <ul class="nav nav-pills pull-right">
                                </ul>
                            </nav>
                            <h3 align="center">Route Black-Hole Portal</h3>
                        </div>
                        <div class="jumbotron">
                            <h3 align="center">Data base Search </h3>
                            <div>
                                <fieldset>

                                    <div ng-if="PrefixFound != 0 && PrefixRemain != 0">
                                        Prefix Found
                                        <button ng-click="Removeentry()">remove Entry?</button>
                                    </div>
                                    <div ng-if="PrefixFound == 0 && AddaPrefix == 0">
                                        No Such prefix in Data Base
                                        <button ng-click="Addentry()">Add Entry?</button>
                                    </div>
                                    <div ng-if="AddaPrefix">
                                        <legend>Enter any Additional BGP Attributes</legend>
                                        <div class="form-group">
                                            <label for="txtNeighbor" class="control-label">Neighbor:</label>
                                            <input type="text" class="form-control" ng-model="info.neighbor" id="txtNeighbor">
                                        </div>
                                        <div class="form-group">
                                            <label for="txtNextHop" class="control-label">NextHop:</label>
                                            <input type="text" class="form-control" ng-model="info.nexthop" id="txtNextHop">
                                        </div>
                                        <div class="form-group">
                                            <label for="txtASPath" class="control-label">ASPath</label>
                                            <input type="text" class="form-control" ng-model="info.aspath" id="txtASPath">
                                        </div>
                                        <div class="form-group">
                                            <label for="txtLocalPref" class="control-label">LocalPref:</label>
                                            <input type="text" class="form-control" ng-model="info.localpref" id="txtLocalPref">
                                        </div>
                                        <div class="form-group">
                                            <label for="txtOperationNotes" class="control-label">OperationNotes:</label>
                                            <input type="text" class="form-control" ng-model="info.opnotes" id="txtOperationNotes">
                                        </div>
                                        <div ng-show="AddSuccess == 0">
                                            <button ng-click="AnnouncePrefix()">Announce the Prefix</button>
                                        </div>
                                        <div ng-if="AddSuccess == info.prefix">
                                            <input type="button" value="Success !!! Refresh the Page For New Request ?" onClick="window.location.reload()">
                                        </div>
                                    </div>
                                    <div>
                                        <div ng-if="DeleteAPrefix == 1">
                                            <div ng-show="DeleteAPrefix == 1 && PrefixRemain != 0">
                                                <button ng-click="DenounceEntry()">Remove the Prefix</button>
                                            </div>
                                            <div ng-if="PrefixRemain == 0">
                                                No Such prefixes Remain in the Data Base !
                                                <input type="button" value="Success !!! Refresh the Page For New Request ?" onClick="window.location.reload()">
                                            </div>
                                        </div>
                                    </div>
                                </fieldset>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </form>

    </div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <!script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script type="text/javascript" src="http://HOST-REF:30100/bower_components/angular/angular.min.js"></script>
    <script type="text/javascript" src="http://HOST-REF:30100/bower_components/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="http://HOST-REF:30100/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="http://HOST-REF:30100/bower_components/ng-ip-address/ngIpAddress.min.js"></script>
    <script type="text/javascript" src="http://HOST-REF:30100/app-ip.js"></script>
    <script type="text/javascript" src="http://HOST-REF:30100/announce_prefix3.js"></script>
</body>

</html>


FlaskApp.wsgi

#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.append('/var/www/ContClBase/ContClBase/')
from MyContainerCl import app as application


MyContainerCl.conf

<VirtualHost *:80>
		ServerName $Svc_Host
		ServerAdmin root@$Svc_Host
		WSGIScriptAlias / /var/www/ContClBase/FlaskApp.wsgi
		<Directory /var/www/ContClBase/ContClBase/>
			Order allow,deny
			Allow from all
		</Directory>
		Alias /static /var/www/ContClBase/ContClBase/static
		<Directory /var/www/ContClBase/ContClBase/static/>
			Order allow,deny
			Allow from all
		</Directory>
		ErrorLog ${APACHE_LOG_DIR}/error.log
		LogLevel warn
		CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>


Dockerfile

############################################################
# Dockerfile to build python/Flask/Mongodb client container images
# Based on Ubuntu
############################################################

# Set the base image to Ubuntu
FROM ubuntu:latest

# File Author / Maintainer
MAINTAINER  Mike Pate

# Update the repository sources list
RUN apt-get update

################## BEGIN INSTALLATION ######################
# Install Model; apps
################## Python ####################
#install python 2.7
RUN apt-get install python -y
RUN apt-get update -y
################## apache server ##############
#install apache server
RUN apt-get install apache2 -y
RUN apt-get update -y
#install wsgi
RUN apt-get install libapache2-mod-wsgi python-dev -y
RUN apt-get update -y
#enable wsgi
RUN a2enmod wsgi 
#
#########create directory structure########
#
RUN mkdir /var/www/ContClBase
RUN mkdir /var/www/ContClBase/ContClBase
RUN mkdir /var/www/ContClBase/ContClBase/static
RUN mkdir /var/www/ContClBase/ContClBase/templates
#
##############copy Flask App to Container ###########
#the actual app below wil be temporarily replaced by a Hello World  app
COPY MyContainerCl.py  /var/www/ContClBase/ContClBase/MyContainerCl.py
COPY sandbox5.html /var/www/ContClBase/ContClBase/templates/sandbox5.html
RUN chmod +x /var/www/ContClBase/ContClBase/MyContainerCl.py
############  Virtual env #####################
#
RUN apt-get install python-pip -y
RUN apt-get update -y
#############   Flask ##########################
RUN pip install Flask 
#
#install additional Flask, Bower, Mongo components
RUN pip install flask-bower
RUN pip install pymongo
# Update the repository sources list once more
RUN apt-get update -y
################ copy virtual host config file to container ########
# COPY MyContainerCl.conf /etc/apache2/sites-available/MyContainerCl.conf
#############enable virtual host #################
# RUN a2ensite MyContainerCl  No! Now Done in wrapper.sh
# copy the  wsgi file into the container  ############
COPY FlaskApp.wsgi /var/www/ContClBase/FlaskApp.wsgi
# expose port 80, since port 80 is the server port as identified in the FlaskApp.conf
EXPOSE  80
# copy cmd wrapper  script containing copying of host file info plus  python script
COPY apache-VH-conf.sh apache-VH-conf.sh
COPY wrapper.sh wrapper.sh
RUN chmod +x apache-VH-conf.sh
RUN chmod +x wrapper.sh
####  restart apache ############
RUN apt-get upgrade -y
# Set default container command
CMD ./wrapper.sh


wrapper.sh

#!bin/bash
echo  "export Svc_Host=e.2a.3da9.ip4.static.sl-reverse.com" >> ~/.bash_login
echo "export Svc_IP=169.61.42.14" >> ~/.bash_login
source ~/.bash_login
sed -i "s/HOST-REF/$Svc_Host/g" /var/www/ContClBase/ContClBase/templates/sandbox5.html
./apache-VH-conf.sh >  /etc/apache2/sites-available/MyContainerCl.conf
a2ensite MyContainerCl
service apache2 restart
python /var/www/ContClBase/ContClBase/MyContainerCl.py &
exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"