diff options
Diffstat (limited to 'core/mongodb')
| -rw-r--r-- | core/mongodb/Dockerfile | 5 | ||||
| -rw-r--r-- | core/mongodb/docker-compose.yml | 30 | ||||
| -rw-r--r-- | core/mongodb/mongo-init-opendc-db.sh | 122 | ||||
| -rwxr-xr-x | core/mongodb/prefab.py | 112 | ||||
| -rwxr-xr-x | core/mongodb/prefabs.py | 124 |
5 files changed, 393 insertions, 0 deletions
diff --git a/core/mongodb/Dockerfile b/core/mongodb/Dockerfile new file mode 100644 index 00000000..b4eb9dd1 --- /dev/null +++ b/core/mongodb/Dockerfile @@ -0,0 +1,5 @@ +FROM mongo:4.2.5 +MAINTAINER Jacob Burley <j.burley@vu.nl> + +# Import init script +ADD mongo-init-opendc-db.sh /docker-entrypoint-initdb.d
\ No newline at end of file diff --git a/core/mongodb/docker-compose.yml b/core/mongodb/docker-compose.yml new file mode 100644 index 00000000..aa54a74c --- /dev/null +++ b/core/mongodb/docker-compose.yml @@ -0,0 +1,30 @@ +version: "3" +services: + mongo: + build: + context: ./ + restart: on-failure + environment: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: rootpassword + MONGO_INITDB_DATABASE: admin + OPENDC_DB: opendc + OPENDC_DB_USERNAME: opendc + OPENDC_DB_PASSWORD: opendcpassword + ports: + - 27017:27017 + #volumes: + # - mongo-volume:/data/db + + mongo-express: + image: mongo-express + restart: on-failure + ports: + - 8082:8081 + environment: + ME_CONFIG_MONGODB_ADMINUSERNAME: root + ME_CONFIG_MONGODB_ADMINPASSWORD: rootpassword + +volumes: + mongo-volume: + external: false diff --git a/core/mongodb/mongo-init-opendc-db.sh b/core/mongodb/mongo-init-opendc-db.sh new file mode 100644 index 00000000..e7a787fe --- /dev/null +++ b/core/mongodb/mongo-init-opendc-db.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +echo 'Creating opendc user and db' + +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("simulations");' +$MONGO_CMD --eval 'db.createCollection("topologies");' +$MONGO_CMD --eval 'db.createCollection("experiments");' +$MONGO_CMD --eval 'db.createCollection("prefabs");' + +echo 'Loading test data' + +$MONGO_CMD --eval 'db.users.insertOne( + { + "googleId": "23483578932789231", + "email": "jorgos.andreadis@gmail.com", + "givenName": "Jorgos", + "familyName": "Andreadis", + "authorizations": [] + });' + +$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/core/mongodb/prefab.py b/core/mongodb/prefab.py new file mode 100755 index 00000000..124f45e3 --- /dev/null +++ b/core/mongodb/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/core/mongodb/prefabs.py b/core/mongodb/prefabs.py new file mode 100755 index 00000000..f6f46cbc --- /dev/null +++ b/core/mongodb/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}) + + |
