diff options
Diffstat (limited to 'opendc-web/opendc-web-api/opendc')
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/api/portfolios.py | 9 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/api/prefabs.py | 19 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/api/projects.py | 28 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/api/scenarios.py | 7 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/api/topologies.py | 10 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/api/traces.py | 6 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/auth.py | 3 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/database.py | 11 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/exts.py | 4 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/models/portfolio.py | 2 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/models/prefab.py | 3 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/models/project.py | 13 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/models/scenario.py | 24 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/models/topology.py | 4 | ||||
| -rw-r--r-- | opendc-web/opendc-web-api/opendc/models/trace.py | 9 |
15 files changed, 94 insertions, 58 deletions
diff --git a/opendc-web/opendc-web-api/opendc/api/portfolios.py b/opendc-web/opendc-web-api/opendc/api/portfolios.py index b07e9da5..84ec466c 100644 --- a/opendc-web/opendc-web-api/opendc/api/portfolios.py +++ b/opendc-web/opendc-web-api/opendc/api/portfolios.py @@ -44,7 +44,7 @@ class Portfolio(Resource): portfolio.check_exists() portfolio.check_user_access(current_user['sub'], False) - data = portfolio.obj + data = PortfolioSchema().dump(portfolio.obj) return {'data': data} def put(self, portfolio_id): @@ -63,7 +63,7 @@ class Portfolio(Resource): portfolio.set_property('targets.repeatsPerScenario', result['portfolio']['targets']['repeatsPerScenario']) portfolio.update() - data = portfolio.obj + data = PortfolioSchema().dump(portfolio.obj) return {'data': data} def delete(self, portfolio_id): @@ -84,7 +84,8 @@ class Portfolio(Resource): project.update() old_object = portfolio.delete() - return {'data': old_object} + data = PortfolioSchema().dump(old_object) + return {'data': data} class PutSchema(Schema): """ @@ -125,7 +126,7 @@ class PortfolioScenarios(Resource): portfolio.obj['scenarioIds'].append(scenario.get_id()) portfolio.update() - data = scenario.obj + data = ScenarioSchema().dump(scenario.obj) return {'data': data} class PostSchema(Schema): diff --git a/opendc-web/opendc-web-api/opendc/api/prefabs.py b/opendc-web/opendc-web-api/opendc/api/prefabs.py index 7bb17e7d..730546ba 100644 --- a/opendc-web/opendc-web-api/opendc/api/prefabs.py +++ b/opendc-web/opendc-web-api/opendc/api/prefabs.py @@ -24,7 +24,6 @@ from flask_restful import Resource from marshmallow import Schema, fields from opendc.models.prefab import Prefab as PrefabModel, PrefabSchema -from opendc.database import Database from opendc.exts import current_user, requires_auth, db @@ -56,14 +55,15 @@ class PrefabList(Resource): result = schema.load(request.json) prefab = PrefabModel(result['prefab']) - prefab.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) - prefab.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + prefab.set_property('datetimeCreated', datetime.now()) + prefab.set_property('datetimeLastEdited', datetime.now()) user_id = current_user['sub'] prefab.set_property('authorId', user_id) prefab.insert() - return {'data': prefab.obj} + data = PrefabSchema().dump(prefab.obj) + return {'data': data} class PostSchema(Schema): """ @@ -83,7 +83,8 @@ class Prefab(Resource): prefab = PrefabModel.from_id(prefab_id) prefab.check_exists() prefab.check_user_access(current_user['sub']) - return {'data': prefab.obj} + data = PrefabSchema().dump(prefab.obj) + return {'data': data} def put(self, prefab_id): """Update a prefab's name and/or contents.""" @@ -97,10 +98,11 @@ class Prefab(Resource): prefab.set_property('name', result['prefab']['name']) prefab.set_property('rack', result['prefab']['rack']) - prefab.set_property('datetime_last_edited', Database.datetime_to_string(datetime.now())) + prefab.set_property('datetimeLastEdited', datetime.now()) prefab.update() - return {'data': prefab.obj} + data = PrefabSchema().dump(prefab.obj) + return {'data': data} def delete(self, prefab_id): """Delete this Prefab.""" @@ -111,7 +113,8 @@ class Prefab(Resource): old_object = prefab.delete() - return {'data': old_object} + data = PrefabSchema().dump(old_object) + return {'data': data} class PutSchema(Schema): """ diff --git a/opendc-web/opendc-web-api/opendc/api/projects.py b/opendc-web/opendc-web-api/opendc/api/projects.py index 8c44b680..05f02a84 100644 --- a/opendc-web/opendc-web-api/opendc/api/projects.py +++ b/opendc-web/opendc-web-api/opendc/api/projects.py @@ -27,7 +27,6 @@ from opendc.models.portfolio import Portfolio, PortfolioSchema from opendc.models.topology import Topology, TopologySchema from opendc.models.project import Project as ProjectModel, ProjectSchema from opendc.exts import current_user, requires_auth -from opendc.database import Database class ProjectList(Resource): @@ -40,7 +39,8 @@ class ProjectList(Resource): """Get the authorized projects of the user""" user_id = current_user['sub'] projects = ProjectModel.get_for_user(user_id) - return {'data': projects} + data = ProjectSchema().dump(projects, many=True) + return {'data': data} def post(self): """Create a new project, and return that new project.""" @@ -53,8 +53,8 @@ class ProjectList(Resource): topology.insert() project = ProjectModel(result['project']) - project.set_property('datetimeCreated', Database.datetime_to_string(datetime.now())) - project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + project.set_property('datetimeCreated', datetime.now()) + project.set_property('datetimeLastEdited', datetime.now()) project.set_property('topologyIds', [topology.get_id()]) project.set_property('portfolioIds', []) project.set_property('authorizations', [{'userId': user_id, 'level': 'OWN'}]) @@ -63,7 +63,8 @@ class ProjectList(Resource): topology.set_property('projectId', project.get_id()) topology.update() - return {'data': project.obj} + data = ProjectSchema().dump(project.obj) + return {'data': data} class Project(Resource): @@ -79,7 +80,8 @@ class Project(Resource): project.check_exists() project.check_user_access(current_user['sub'], False) - return {'data': project.obj} + data = ProjectSchema().dump(project.obj) + return {'data': data} def put(self, project_id): """Update a project's name.""" @@ -92,10 +94,11 @@ class Project(Resource): project.check_user_access(current_user['sub'], True) project.set_property('name', result['project']['name']) - project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + project.set_property('datetimeLastEdited', datetime.now()) project.update() - return {'data': project.obj} + data = ProjectSchema().dump(project.obj) + return {'data': data} def delete(self, project_id): """Delete this Project.""" @@ -113,8 +116,8 @@ class Project(Resource): portfolio.delete() old_object = project.delete() - - return {'data': old_object} + data = ProjectSchema().dump(old_object) + return {'data': data} class PutSchema(Schema): """ @@ -148,10 +151,11 @@ class ProjectTopologies(Resource): topology.insert() project.obj['topologyIds'].append(topology.get_id()) - project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + project.set_property('datetimeLastEdited', datetime.now()) project.update() - return {'data': topology.obj} + data = TopologySchema().dump(topology.obj) + return {'data': data} class PutSchema(Schema): """ diff --git a/opendc-web/opendc-web-api/opendc/api/scenarios.py b/opendc-web/opendc-web-api/opendc/api/scenarios.py index b566950a..234bdec1 100644 --- a/opendc-web/opendc-web-api/opendc/api/scenarios.py +++ b/opendc-web/opendc-web-api/opendc/api/scenarios.py @@ -38,7 +38,7 @@ class Scenario(Resource): scenario = ScenarioModel.from_id(scenario_id) scenario.check_exists() scenario.check_user_access(current_user['sub'], False) - data = scenario.obj + data = ScenarioSchema().dump(scenario.obj) return {'data': data} def put(self, scenario_id): @@ -54,7 +54,7 @@ class Scenario(Resource): scenario.set_property('name', result['scenario']['name']) scenario.update() - data = scenario.obj + data = ScenarioSchema().dump(scenario.obj) return {'data': data} def delete(self, scenario_id): @@ -72,7 +72,8 @@ class Scenario(Resource): portfolio.update() old_object = scenario.delete() - return {'data': old_object} + data = ScenarioSchema().dump(old_object) + return {'data': data} class PutSchema(Schema): """ diff --git a/opendc-web/opendc-web-api/opendc/api/topologies.py b/opendc-web/opendc-web-api/opendc/api/topologies.py index eedf049d..a2d3f41a 100644 --- a/opendc-web/opendc-web-api/opendc/api/topologies.py +++ b/opendc-web/opendc-web-api/opendc/api/topologies.py @@ -24,7 +24,6 @@ from flask import request from flask_restful import Resource from marshmallow import Schema, fields -from opendc.database import Database from opendc.models.project import Project from opendc.models.topology import Topology as TopologyModel, TopologySchema from opendc.exts import current_user, requires_auth @@ -43,7 +42,7 @@ class Topology(Resource): topology = TopologyModel.from_id(topology_id) topology.check_exists() topology.check_user_access(current_user['sub'], False) - data = topology.obj + data = TopologySchema().dump(topology.obj) return {'data': data} def put(self, topology_id): @@ -60,10 +59,10 @@ class Topology(Resource): topology.set_property('name', result['topology']['name']) topology.set_property('rooms', result['topology']['rooms']) - topology.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now())) + topology.set_property('datetimeLastEdited', datetime.now()) topology.update() - data = topology.obj + data = TopologySchema().dump(topology.obj) return {'data': data} def delete(self, topology_id): @@ -84,7 +83,8 @@ class Topology(Resource): project.update() old_object = topology.delete() - return {'data': old_object} + data = TopologySchema().dump(old_object) + return {'data': data} class PutSchema(Schema): """ diff --git a/opendc-web/opendc-web-api/opendc/api/traces.py b/opendc-web/opendc-web-api/opendc/api/traces.py index f685f00c..6be8c5e5 100644 --- a/opendc-web/opendc-web-api/opendc/api/traces.py +++ b/opendc-web/opendc-web-api/opendc/api/traces.py @@ -21,7 +21,7 @@ from flask_restful import Resource from opendc.exts import requires_auth -from opendc.models.trace import Trace as TraceModel +from opendc.models.trace import Trace as TraceModel, TraceSchema class TraceList(Resource): @@ -33,7 +33,7 @@ class TraceList(Resource): def get(self): """Get all available Traces.""" traces = TraceModel.get_all() - data = traces.obj + data = TraceSchema().dump(traces.obj, many=True) return {'data': data} @@ -47,5 +47,5 @@ class Trace(Resource): """Get trace information by identifier.""" trace = TraceModel.from_id(trace_id) trace.check_exists() - data = trace.obj + data = TraceSchema().dump(trace.obj) return {'data': data} diff --git a/opendc-web/opendc-web-api/opendc/auth.py b/opendc-web/opendc-web-api/opendc/auth.py index 1870f01c..6db06fb1 100644 --- a/opendc-web/opendc-web-api/opendc/auth.py +++ b/opendc-web/opendc-web-api/opendc/auth.py @@ -42,8 +42,7 @@ def get_token(): if parts[0].lower() != "bearer": raise AuthError({ "code": "invalid_header", - "description": "Authorization header must start with" - " Bearer" + "description": "Authorization header must start with Bearer" }, 401) if len(parts) == 1: raise AuthError({"code": "invalid_header", "description": "Token not found"}, 401) diff --git a/opendc-web/opendc-web-api/opendc/database.py b/opendc-web/opendc-web-api/opendc/database.py index f9a33b66..37fd1a4d 100644 --- a/opendc-web/opendc-web-api/opendc/database.py +++ b/opendc-web/opendc-web-api/opendc/database.py @@ -19,7 +19,6 @@ # SOFTWARE. import urllib.parse -from datetime import datetime from pymongo import MongoClient @@ -90,13 +89,3 @@ class Database: The query needs to be in json format, i.e.: `{'name': prefab_name}`. """ getattr(self.opendc_db, collection).delete_many(query) - - @staticmethod - def datetime_to_string(datetime_to_convert): - """Return a database-compatible string representation of the given datetime object.""" - return datetime_to_convert.strftime(DATETIME_STRING_FORMAT) - - @staticmethod - def string_to_datetime(string_to_convert): - """Return a datetime corresponding to the given string representation.""" - return datetime.strptime(string_to_convert, DATETIME_STRING_FORMAT) diff --git a/opendc-web/opendc-web-api/opendc/exts.py b/opendc-web/opendc-web-api/opendc/exts.py index f088a29c..d24f7197 100644 --- a/opendc-web/opendc-web-api/opendc/exts.py +++ b/opendc-web/opendc-web-api/opendc/exts.py @@ -34,8 +34,7 @@ def get_auth_context(): _auth_context = AuthContext( alg=AsymmetricJwtAlgorithm(jwks_url=f"https://{os.environ['AUTH0_DOMAIN']}/.well-known/jwks.json"), issuer=f"https://{os.environ['AUTH0_DOMAIN']}/", - audience=os.environ['AUTH0_AUDIENCE'] - ) + audience=os.environ['AUTH0_AUDIENCE']) g.auth_context = _auth_context return _auth_context @@ -46,7 +45,6 @@ auth_context = LocalProxy(get_auth_context) def requires_auth(f): """Decorator to determine if the Access Token is valid. """ - @wraps(f) def decorated(*args, **kwargs): token = get_token() diff --git a/opendc-web/opendc-web-api/opendc/models/portfolio.py b/opendc-web/opendc-web-api/opendc/models/portfolio.py index aff1d3f0..1643e23e 100644 --- a/opendc-web/opendc-web-api/opendc/models/portfolio.py +++ b/opendc-web/opendc-web-api/opendc/models/portfolio.py @@ -16,7 +16,7 @@ class PortfolioSchema(Schema): """ Schema representing a portfolio. """ - _id = fields.String() + _id = fields.String(dump_only=True) projectId = fields.String() name = fields.String(required=True) scenarioIds = fields.List(fields.String()) diff --git a/opendc-web/opendc-web-api/opendc/models/prefab.py b/opendc-web/opendc-web-api/opendc/models/prefab.py index d83ef4cb..5e4b81dc 100644 --- a/opendc-web/opendc-web-api/opendc/models/prefab.py +++ b/opendc-web/opendc-web-api/opendc/models/prefab.py @@ -9,7 +9,8 @@ class PrefabSchema(Schema): """ Schema for a Prefab. """ - _id = fields.String() + _id = fields.String(dump_only=True) + authorId = fields.String(dump_only=True) name = fields.String(required=True) datetimeCreated = fields.DateTime() datetimeLastEdited = fields.DateTime() diff --git a/opendc-web/opendc-web-api/opendc/models/project.py b/opendc-web/opendc-web-api/opendc/models/project.py index ee84c73e..f2b3b564 100644 --- a/opendc-web/opendc-web-api/opendc/models/project.py +++ b/opendc-web/opendc-web-api/opendc/models/project.py @@ -1,20 +1,29 @@ -from marshmallow import Schema, fields +from marshmallow import Schema, fields, validate from werkzeug.exceptions import Forbidden from opendc.models.model import Model from opendc.exts import db +class ProjectAuthorizations(Schema): + """ + Schema representing a project authorization. + """ + userId = fields.String(required=True) + level = fields.String(required=True, validate=validate.OneOf(["VIEW", "EDIT", "OWN"])) + + class ProjectSchema(Schema): """ Schema representing a Project. """ - _id = fields.String() + _id = fields.String(dump_only=True) name = fields.String(required=True) datetimeCreated = fields.DateTime() datetimeLastEdited = fields.DateTime() topologyIds = fields.List(fields.String()) portfolioIds = fields.List(fields.String()) + authorizations = fields.List(fields.Nested(ProjectAuthorizations)) class Project(Model): diff --git a/opendc-web/opendc-web-api/opendc/models/scenario.py b/opendc-web/opendc-web-api/opendc/models/scenario.py index 2911b1ae..658d790e 100644 --- a/opendc-web/opendc-web-api/opendc/models/scenario.py +++ b/opendc-web/opendc-web-api/opendc/models/scenario.py @@ -34,17 +34,39 @@ class OperationalSchema(Schema): schedulerName = fields.String() +class ResultSchema(Schema): + """ + Schema representing the simulation results. + """ + max_num_deployed_images = fields.List(fields.Number()) + max_cpu_demand = fields.List(fields.Number()) + max_cpu_usage = fields.List(fields.Number()) + mean_num_deployed_images = fields.List(fields.Number()) + total_failure_slices = fields.List(fields.Number()) + total_failure_vm_slices = fields.List(fields.Number()) + total_granted_burst = fields.List(fields.Number()) + total_interfered_burst = fields.List(fields.Number()) + total_overcommitted_burst = fields.List(fields.Number()) + total_power_draw = fields.List(fields.Number()) + total_requested_burst = fields.List(fields.Number()) + total_vms_failed = fields.List(fields.Number()) + total_vms_finished = fields.List(fields.Number()) + total_vms_queued = fields.List(fields.Number()) + total_vms_submitted = fields.List(fields.Number()) + + class ScenarioSchema(Schema): """ Schema representing a scenario. """ - _id = fields.String() + _id = fields.String(dump_only=True) portfolioId = fields.String() name = fields.String(required=True) simulation = fields.Nested(SimulationSchema) trace = fields.Nested(TraceSchema) topology = fields.Nested(TopologySchema) operational = fields.Nested(OperationalSchema) + results = fields.Nested(ResultSchema, dump_only=True) class Scenario(Model): diff --git a/opendc-web/opendc-web-api/opendc/models/topology.py b/opendc-web/opendc-web-api/opendc/models/topology.py index c6354ae6..71d2cade 100644 --- a/opendc-web/opendc-web-api/opendc/models/topology.py +++ b/opendc-web/opendc-web-api/opendc/models/topology.py @@ -72,8 +72,8 @@ class TopologySchema(Schema): """ Schema representing a datacenter topology. """ - _id = fields.String() - projectId = fields.String() + _id = fields.String(dump_only=True) + projectId = fields.String(dump_only=True) name = fields.String(required=True) rooms = fields.List(fields.Nested(RoomSchema), required=True) diff --git a/opendc-web/opendc-web-api/opendc/models/trace.py b/opendc-web/opendc-web-api/opendc/models/trace.py index 2f6e4926..69287f29 100644 --- a/opendc-web/opendc-web-api/opendc/models/trace.py +++ b/opendc-web/opendc-web-api/opendc/models/trace.py @@ -1,6 +1,15 @@ +from marshmallow import Schema, fields + from opendc.models.model import Model +class TraceSchema(Schema): + """Schema for a Trace.""" + _id = fields.String(dump_only=True) + name = fields.String() + type = fields.String() + + class Trace(Model): """Model representing a Trace.""" |
