summaryrefslogtreecommitdiff
path: root/database
diff options
context:
space:
mode:
Diffstat (limited to 'database')
-rw-r--r--database/Dockerfile5
-rw-r--r--database/mongo-init-opendc-db.sh115
-rwxr-xr-xdatabase/prefab.py112
-rwxr-xr-xdatabase/prefabs.py124
4 files changed, 356 insertions, 0 deletions
diff --git a/database/Dockerfile b/database/Dockerfile
new file mode 100644
index 00000000..12803f8e
--- /dev/null
+++ b/database/Dockerfile
@@ -0,0 +1,5 @@
+FROM mongo:4.2.8
+MAINTAINER Jacob Burley <j.burley@vu.nl>
+
+# Import init script
+ADD mongo-init-opendc-db.sh /docker-entrypoint-initdb.d
diff --git a/database/mongo-init-opendc-db.sh b/database/mongo-init-opendc-db.sh
new file mode 100644
index 00000000..44fa75a3
--- /dev/null
+++ b/database/mongo-init-opendc-db.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+echo 'Creating OpenDC user and database'
+
+mongo opendc --host localhost \
+ --port 27017 \
+ -u "$MONGO_INITDB_ROOT_USERNAME" \
+ -p "$MONGO_INITDB_ROOT_PASSWORD" \
+ --authenticationDatabase admin \
+ --eval "db.createUser({user: '$OPENDC_DB_USERNAME', pwd: '$OPENDC_DB_PASSWORD', roles:[{role:'dbOwner', db: '$OPENDC_DB'}]});"
+
+MONGO_CMD="mongo $OPENDC_DB -u $OPENDC_DB_USERNAME -p $OPENDC_DB_PASSWORD --authenticationDatabase $OPENDC_DB"
+
+echo 'Creating collections'
+
+$MONGO_CMD --eval 'db.createCollection("users");'
+$MONGO_CMD --eval 'db.createCollection("projects");'
+$MONGO_CMD --eval 'db.createCollection("topologies");'
+$MONGO_CMD --eval 'db.createCollection("portfolios");'
+$MONGO_CMD --eval 'db.createCollection("scenarios");'
+$MONGO_CMD --eval 'db.createCollection("traces");'
+$MONGO_CMD --eval 'db.createCollection("prefabs");'
+
+echo 'Loading test data'
+
+$MONGO_CMD --eval 'db.prefabs.insertOne(
+ {
+ "type": "rack",
+ "name": "testRack3",
+ "size": 42,
+ "depth": 42,
+ "author": "Jacob Burley",
+ "visibility": "public",
+ "children": [
+ {
+ "type": "switch",
+ "ports": 48,
+ "powerDraw": 150,
+ "psus": 1,
+ "size": 1
+ },
+ {
+ "type": "chassis",
+ "size": 4,
+ "children": [
+ {
+ "type": "mainboard",
+ "sockets": 1,
+ "dimmSlots": 4,
+ "nics": 1,
+ "pcieSlots": 2,
+ "children": [
+ {
+ "type": "CPU",
+ "coreCount": 4,
+ "SMT": true,
+ "baseClk": 3.5,
+ "boostClk": 3.9,
+ "brand": "Intel",
+ "SKU": "i7-3770K",
+ "socket": "LGA1155",
+ "TDP": 77
+ },
+ {
+ "type": "DDR3",
+ "capacity": 4096,
+ "memfreq": 1333,
+ "ecc": false
+ },
+ {
+ "type": "DDR3",
+ "capacity": 4096,
+ "memfreq": 1333,
+ "ecc": false
+ },
+ {
+ "type": "DDR3",
+ "capacity": 4096,
+ "memfreq": 1333,
+ "ecc": false
+ },
+ {
+ "type": "DDR3",
+ "capacity": 4096,
+ "memfreq": 1333,
+ "ecc": false
+ },
+ {
+ "type": "GPU",
+ "VRAM": 8192,
+ "coreCount": 2304,
+ "brand": "AMD",
+ "technologies": "OpenCL",
+ "pcieGen": "3x16",
+ "tdp": 169,
+ "slots": 2
+ }
+ ]
+ },
+ {
+ "type": "PSU",
+ "wattage": 550,
+ "ac": true
+ },
+ {
+ "type": "disk",
+ "size": 2000,
+ "interface": "SATA",
+ "media": "flash",
+ "formFactor": 2.5
+ }
+ ]
+ }
+ ]
+ });'
diff --git a/database/prefab.py b/database/prefab.py
new file mode 100755
index 00000000..124f45e3
--- /dev/null
+++ b/database/prefab.py
@@ -0,0 +1,112 @@
+#!/Users/jacobburley/thesis-src/opendc/mongodb/opendc_testing/bin/python3
+#Change shebang to /usr/bin/python3 before using with docker
+# encoding: utf-8
+"""
+prefab
+
+CLI frontend for viewing, modifying and creating prefabs in OpenDC.
+
+"""
+import sys
+import prefabs
+
+def usage():
+ print("Usage: prefab add <prefab>: imports a prefab from JSON")
+ print(" list: lists all (public) prefabs")
+ print(" export <prefab> [json|yaml]: exports the specified prefab to the specified filetype (with JSON used by default)")
+ print(" clone <prefab> [new prefab name]: clones the specified prefab, giving the new prefab a name if specified")
+ print(" remove <prefab>: removes the specified prefab from the database")
+
+def interactive(): #interactive CLI mode: recommended
+ print("OpenDC Prefab CLI")
+ running = True
+ while(exit):
+ print(">", end=" ")
+ try:
+ command = input()
+ command = command.split()
+ except EOFError as e:
+ print("exit")
+ print("bye!")
+ exit()
+ except KeyboardInterrupt as KI:
+ print("\nbye!")
+ exit()
+ if(len(command) >= 1):
+ if(command[0] == "exit"):
+ print("bye!")
+ exit()
+ elif(command[0] == "list"): # decrypt
+ prefabs.list()
+ elif(command[0] == "help"): # decrypt
+ usage()
+ elif(command[0] == "add"):
+ if(len(command) == 3):
+ prefabs.add(command[1], command[2])
+ else:
+ prefabs.add(command[1], None)
+ elif(command[0] == "clone"):
+ if(len(command) == 3):
+ prefabs.clone(command[1], command[2])
+ else:
+ prefabs.clone(command[1], None)
+ elif(command[0] == "export"):
+ #print(sys.argv[2])
+ prefabs.export(command[1], "json")
+ elif(command[0] == "remove"):
+ print("WARNING: Doing so will permanently remove the specified prefab. \nThis action CANNOT be undone. Please type the name of the prefab to confirm deletion.")
+ confirm = input()
+ if confirm == command[1]:
+ prefabs.remove(command[1])
+ print(f'Prefab {command[1]} has been removed.')
+ else:
+ print("Confirmation failed. The prefab has not been removed.")
+ else:
+ print("prefabs: try 'help' for more information\n")
+ else:
+ print("prefabs: try 'help' for more information\n")
+
+
+def main():
+ if(len(sys.argv) >= 2):
+ if(sys.argv[1] == "list"): # decrypt
+ prefabs.list()
+ exit()
+ #elif(sys.argv[1] == "-e"): # encrypt
+ # encrypt(sys.argv[2], sys.argv[3], sys.argv[4])
+ #elif(sys.argv[1] == "-v"): # verify
+ # verify(sys.argv[2], sys.argv[3], sys.argv[4])
+ elif(sys.argv[1] == "help"): # decrypt
+ usage()
+ exit()
+ elif(sys.argv[1] == "add"):
+ if(sys.argv[3]):
+ prefabs.add(sys.argv[2], sys.argv[3])
+ else:
+ prefabs.add(sys.argv[2])
+ exit()
+ elif(sys.argv[1] == "export"):
+ #print(sys.argv[2])
+ prefabs.export(sys.argv[2], "json")
+ exit()
+ elif(sys.argv[1] == "remove"):
+ print("WARNING: Doing so will permanently remove the specified prefab. \nThis action CANNOT be undone. Please type the name of the prefab to confirm deletion.")
+ confirm = input()
+ if confirm == sys.argv[2]:
+ prefabs.remove(sys.argv[2])
+ print(f'Prefab {sys.argv[2]} has been removed.')
+ else:
+ print("Confirmation failed. The prefab has not been removed.")
+ exit()
+ else:
+ print("prefabs: try 'prefabs help' for more information\n")
+ elif(len(sys.argv) == 1):
+ interactive()
+
+ else:
+ # print "Incorrect number of arguments!\n"
+ print("prefabs: try 'prefabs help' for more information\n")
+
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/database/prefabs.py b/database/prefabs.py
new file mode 100755
index 00000000..f6f46cbc
--- /dev/null
+++ b/database/prefabs.py
@@ -0,0 +1,124 @@
+#!/Users/jacobburley/thesis-src/opendc/mongodb/opendc_testing/bin/python3
+#Change shebang to /usr/bin/python3 before using with docker
+# encoding: utf-8
+"""
+prefabs
+
+Python Library for interacting with mongoDB prefabs collection.
+
+"""
+import urllib.parse
+import pprint
+import sys
+import os
+import json
+import re
+import ujson
+#import pyyaml
+
+from pymongo import MongoClient
+from bson.json_util import loads, dumps, RELAXED_JSON_OPTIONS, CANONICAL_JSON_OPTIONS
+
+#mongodb_opendc_db = os.environ['OPENDC_DB']
+#mongodb_opendc_user = os.environ['OPENDC_DB_USERNAME']
+#mongodb_opendc_password = os.environ['OPENDC_DB_PASSWORD']
+
+#if mongodb_opendc_db == None or mongodb_opendc_user == None or mongodb_opendc_password == None:
+# print("One or more environment variables are not set correctly. \nYou may experience issues connecting to the mongodb database.")
+
+user = urllib.parse.quote_plus('opendc') #TODO: replace this with environment variable
+password = urllib.parse.quote_plus('opendcpassword') #TODO: same as above
+database = urllib.parse.quote_plus('opendc')
+
+client = MongoClient('mongodb://%s:%s@localhost/default_db?authSource=%s' % (user, password, database))
+opendcdb = client.opendc
+prefabs_collection = opendcdb.prefabs
+
+
+def add(prefab_file, name):
+ if(re.match(r"\w+(\\\ \w*)*\.json", prefab_file)):
+ try:
+ with open(prefab_file, "r") as json_file:
+ json_prefab = json.load(json_file)
+ #print(json_prefab)
+ if name != None:
+ json_prefab["name"] = name
+ try:
+ prefab_id = prefabs_collection.insert(json_prefab)
+ except ConnectionFailure:
+ print("ERROR: Could not connect to the mongoDB database.")
+ except DuplicateKeyError:
+ print("ERROR: A prefab with the same unique ID already exists in the database. \nPlease remove the '_id' before trying again.\nYour prefab has not been imported.")
+ except:
+ print("ERROR: A general error has occurred. Your prefab has not been imported.")
+ if prefab_id != None:
+ if name != None:
+ print(f'Prefab "{name}" has been imported successfully.')
+ else:
+ print(f'Prefab "{prefab_file}" has been imported successfully.')
+ except FileNotFoundError:
+ print(f"ERROR: {prefab_file} could not be found in the specified path. No prefabs have been imported.")
+ elif(re.match(r"\w+(\\\ \w*)*\.yml", prefab_file)):
+ print("expecting a yaml file here")
+ #yaml
+ else:
+ print("The filetype provided is an unsupported filetype.")
+ #unsupported filetype
+
+def clone(prefab_name, new_name):
+ bson = prefabs_collection.find_one({'name': prefab_name})
+ json_string = dumps(bson) #convert BSON representation to JSON
+ chosen_prefab = json.loads(json_string) #load as a JSON object
+
+ chosen_prefab.pop("_id") # clean out our _id field from the export: mongo will generate a new one if this is imported back in
+
+ if new_name != None:
+ chosen_prefab["name"] = new_name
+ try:
+ prefab_id = prefabs_collection.insert_one(chosen_prefab)
+ except ConnectionFailure:
+ print("ERROR: Could not connect to the mongoDB database.")
+ except:
+ print("ERROR: A general error has occurred. Your selected prefab has not been cloned.")
+ if prefab_id != None:
+ if new_name != None:
+ print(f'Prefab "{prefab_name}" has been cloned successfully as {new_name}.')
+ else:
+ print(f'Prefab "{prefab_name}" has been cloned successfully.')
+
+def export(prefab_name, type):
+ bson = prefabs_collection.find_one({'name': prefab_name})
+ json_string = dumps(bson) #convert BSON representation to JSON
+ chosen_prefab = json.loads(json_string) #load as a JSON object
+
+ chosen_prefab.pop("_id") # clean out our _id field from the export: mongo will generate a new one if this is imported back in
+
+ with open(f'{prefab_name}.json', 'w', encoding='utf8') as f:
+ json.dump(chosen_prefab, f, ensure_ascii=False, indent=4)
+ print(f'Prefab {prefab_name} written to {os.getcwd()}/{prefab_name}.json.')
+ #pprint.pprint(json_string)
+ #pprint.pprint(json.loads(str(json_string)))
+
+def list():
+ #TODO: why does it output in single quotations?
+ cursor = prefabs_collection.find()
+ prefabs = []
+ for record in cursor:
+ #pprint.pprint(record)
+ #print(record)
+ json_string = dumps(record, json_options=RELAXED_JSON_OPTIONS) ##pymongo retrieves BSON objects, which need to be converted to json for pythons json module
+ prefabs.append(json.loads(json_string))
+
+ #print(f'There are {str(len(prefabs))} prefabs in the database. They are:')
+ print("Name Author")
+ for prefab in prefabs:
+ if(prefab['visibility'] == "private"):
+ continue
+ print(f"{prefab['name']} {prefab['author']}")
+ #pprint.pprint(prefab)
+
+
+def remove(prefab_name):
+ prefabs_collection.delete_one({'name': prefab_name})
+
+