summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-api/opendc/api
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-api/opendc/api')
-rw-r--r--opendc-web/opendc-web-api/opendc/api/__init__.py0
-rw-r--r--opendc-web/opendc-web-api/opendc/api/jobs.py105
-rw-r--r--opendc-web/opendc-web-api/opendc/api/portfolios.py153
-rw-r--r--opendc-web/opendc-web-api/opendc/api/prefabs.py123
-rw-r--r--opendc-web/opendc-web-api/opendc/api/projects.py224
-rw-r--r--opendc-web/opendc-web-api/opendc/api/scenarios.py86
-rw-r--r--opendc-web/opendc-web-api/opendc/api/schedulers.py46
-rw-r--r--opendc-web/opendc-web-api/opendc/api/topologies.py97
-rw-r--r--opendc-web/opendc-web-api/opendc/api/traces.py51
9 files changed, 0 insertions, 885 deletions
diff --git a/opendc-web/opendc-web-api/opendc/api/__init__.py b/opendc-web/opendc-web-api/opendc/api/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/opendc-web/opendc-web-api/opendc/api/__init__.py
+++ /dev/null
diff --git a/opendc-web/opendc-web-api/opendc/api/jobs.py b/opendc-web/opendc-web-api/opendc/api/jobs.py
deleted file mode 100644
index 6fb0522b..00000000
--- a/opendc-web/opendc-web-api/opendc/api/jobs.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-from flask import request
-from flask_restful import Resource
-from marshmallow import fields, Schema, validate
-from werkzeug.exceptions import BadRequest, Conflict
-
-from opendc.exts import requires_auth, requires_scope
-from opendc.models.scenario import Scenario
-
-
-def convert_to_job(scenario):
- """Convert a scenario to a job.
- """
- return JobSchema().dump({
- '_id': scenario['_id'],
- 'scenarioId': scenario['_id'],
- 'state': scenario['simulation']['state'],
- 'heartbeat': scenario['simulation'].get('heartbeat', None),
- 'results': scenario.get('results', {})
- })
-
-
-class JobSchema(Schema):
- """
- Schema representing a simulation job.
- """
- _id = fields.String(dump_only=True)
- scenarioId = fields.String(dump_only=True)
- state = fields.String(required=True,
- validate=validate.OneOf(["QUEUED", "CLAIMED", "RUNNING", "FINISHED", "FAILED"]))
- heartbeat = fields.DateTime()
- results = fields.Dict()
-
-
-class JobList(Resource):
- """
- Resource representing the list of available jobs.
- """
- method_decorators = [requires_auth, requires_scope('runner')]
-
- def get(self):
- """Get all available jobs."""
- jobs = Scenario.get_jobs()
- data = list(map(convert_to_job, jobs.obj))
- return {'data': data}
-
-
-class Job(Resource):
- """
- Resource representing a single job.
- """
- method_decorators = [requires_auth, requires_scope('runner')]
-
- def get(self, job_id):
- """Get the details of a single job."""
- job = Scenario.from_id(job_id)
- job.check_exists()
- data = convert_to_job(job.obj)
- return {'data': data}
-
- def post(self, job_id):
- """Update the details of a single job."""
- action = JobSchema(only=('state', 'results')).load(request.json)
-
- job = Scenario.from_id(job_id)
- job.check_exists()
-
- old_state = job.obj['simulation']['state']
- new_state = action['state']
-
- if old_state == new_state:
- data = job.update_state(new_state)
- elif (old_state, new_state) == ('QUEUED', 'CLAIMED'):
- data = job.update_state('CLAIMED')
- elif (old_state, new_state) == ('CLAIMED', 'RUNNING'):
- data = job.update_state('RUNNING')
- elif (old_state, new_state) == ('RUNNING', 'FINISHED'):
- data = job.update_state('FINISHED', results=action.get('results', None))
- elif old_state in ('CLAIMED', 'RUNNING') and new_state == 'FAILED':
- data = job.update_state('FAILED')
- else:
- raise BadRequest('Invalid state transition')
-
- if not data:
- raise Conflict('State conflict')
-
- return {'data': convert_to_job(data)}
diff --git a/opendc-web/opendc-web-api/opendc/api/portfolios.py b/opendc-web/opendc-web-api/opendc/api/portfolios.py
deleted file mode 100644
index 4d8f54fd..00000000
--- a/opendc-web/opendc-web-api/opendc/api/portfolios.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from flask import request
-from flask_restful import Resource
-from marshmallow import Schema, fields
-
-from opendc.exts import requires_auth, current_user, has_scope
-from opendc.models.portfolio import Portfolio as PortfolioModel, PortfolioSchema
-from opendc.models.project import Project
-from opendc.models.scenario import ScenarioSchema, Scenario
-from opendc.models.topology import Topology
-
-
-class Portfolio(Resource):
- """
- Resource representing a portfolio.
- """
- method_decorators = [requires_auth]
-
- def get(self, portfolio_id):
- """
- Get a portfolio by identifier.
- """
- portfolio = PortfolioModel.from_id(portfolio_id)
-
- portfolio.check_exists()
-
- # Users with scope runner can access all portfolios
- if not has_scope('runner'):
- portfolio.check_user_access(current_user['sub'], False)
-
- data = PortfolioSchema().dump(portfolio.obj)
- return {'data': data}
-
- def put(self, portfolio_id):
- """
- Replace the portfolio.
- """
- schema = Portfolio.PutSchema()
- result = schema.load(request.json)
-
- portfolio = PortfolioModel.from_id(portfolio_id)
- portfolio.check_exists()
- portfolio.check_user_access(current_user['sub'], True)
-
- portfolio.set_property('name', result['portfolio']['name'])
- portfolio.set_property('targets.enabledMetrics', result['portfolio']['targets']['enabledMetrics'])
- portfolio.set_property('targets.repeatsPerScenario', result['portfolio']['targets']['repeatsPerScenario'])
-
- portfolio.update()
- data = PortfolioSchema().dump(portfolio.obj)
- return {'data': data}
-
- def delete(self, portfolio_id):
- """
- Delete a portfolio.
- """
- portfolio = PortfolioModel.from_id(portfolio_id)
-
- portfolio.check_exists()
- portfolio.check_user_access(current_user['sub'], True)
-
- portfolio_id = portfolio.get_id()
-
- project = Project.from_id(portfolio.obj['projectId'])
- project.check_exists()
- if portfolio_id in project.obj['portfolioIds']:
- project.obj['portfolioIds'].remove(portfolio_id)
- project.update()
-
- old_object = portfolio.delete()
- data = PortfolioSchema().dump(old_object)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the PUT operation on a portfolio.
- """
- portfolio = fields.Nested(PortfolioSchema, required=True)
-
-
-class PortfolioScenarios(Resource):
- """
- Resource representing the scenarios of a portfolio.
- """
- method_decorators = [requires_auth]
-
- def get(self, portfolio_id):
- """
- Get all scenarios belonging to a portfolio.
- """
- portfolio = PortfolioModel.from_id(portfolio_id)
-
- portfolio.check_exists()
- portfolio.check_user_access(current_user['sub'], True)
-
- scenarios = Scenario.get_for_portfolio(portfolio_id)
-
- data = ScenarioSchema().dump(scenarios, many=True)
- return {'data': data}
-
- def post(self, portfolio_id):
- """
- Add a new scenario to this portfolio
- """
- schema = PortfolioScenarios.PostSchema()
- result = schema.load(request.json)
-
- portfolio = PortfolioModel.from_id(portfolio_id)
-
- portfolio.check_exists()
- portfolio.check_user_access(current_user['sub'], True)
-
- scenario = Scenario(result['scenario'])
-
- topology = Topology.from_id(scenario.obj['topology']['topologyId'])
- topology.check_exists()
- topology.check_user_access(current_user['sub'], True)
-
- scenario.set_property('portfolioId', portfolio.get_id())
- scenario.set_property('simulation', {'state': 'QUEUED'})
- scenario.set_property('topology.topologyId', topology.get_id())
-
- scenario.insert()
-
- portfolio.obj['scenarioIds'].append(scenario.get_id())
- portfolio.update()
- data = ScenarioSchema().dump(scenario.obj)
- return {'data': data}
-
- class PostSchema(Schema):
- """
- Schema for the POST operation on a portfolio's scenarios.
- """
- scenario = fields.Nested(ScenarioSchema, required=True)
diff --git a/opendc-web/opendc-web-api/opendc/api/prefabs.py b/opendc-web/opendc-web-api/opendc/api/prefabs.py
deleted file mode 100644
index 730546ba..00000000
--- a/opendc-web/opendc-web-api/opendc/api/prefabs.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from datetime import datetime
-from flask import request
-from flask_restful import Resource
-from marshmallow import Schema, fields
-
-from opendc.models.prefab import Prefab as PrefabModel, PrefabSchema
-from opendc.exts import current_user, requires_auth, db
-
-
-class PrefabList(Resource):
- """
- Resource for the list of prefabs available to the user.
- """
- method_decorators = [requires_auth]
-
- def get(self):
- """
- Get the available prefabs for a user.
- """
- user_id = current_user['sub']
-
- own_prefabs = db.fetch_all({'authorId': user_id}, PrefabModel.collection_name)
- public_prefabs = db.fetch_all({'visibility': 'public'}, PrefabModel.collection_name)
-
- authorizations = {"authorizations": []}
- authorizations["authorizations"].append(own_prefabs)
- authorizations["authorizations"].append(public_prefabs)
- return {'data': authorizations}
-
- def post(self):
- """
- Create a new prefab.
- """
- schema = PrefabList.PostSchema()
- result = schema.load(request.json)
-
- prefab = PrefabModel(result['prefab'])
- 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()
- data = PrefabSchema().dump(prefab.obj)
- return {'data': data}
-
- class PostSchema(Schema):
- """
- Schema for the POST operation on the prefab list.
- """
- prefab = fields.Nested(PrefabSchema, required=True)
-
-
-class Prefab(Resource):
- """
- Resource representing a single prefab.
- """
- method_decorators = [requires_auth]
-
- def get(self, prefab_id):
- """Get this Prefab."""
- prefab = PrefabModel.from_id(prefab_id)
- prefab.check_exists()
- prefab.check_user_access(current_user['sub'])
- data = PrefabSchema().dump(prefab.obj)
- return {'data': data}
-
- def put(self, prefab_id):
- """Update a prefab's name and/or contents."""
-
- schema = Prefab.PutSchema()
- result = schema.load(request.json)
-
- prefab = PrefabModel.from_id(prefab_id)
- prefab.check_exists()
- prefab.check_user_access(current_user['sub'])
-
- prefab.set_property('name', result['prefab']['name'])
- prefab.set_property('rack', result['prefab']['rack'])
- prefab.set_property('datetimeLastEdited', datetime.now())
- prefab.update()
-
- data = PrefabSchema().dump(prefab.obj)
- return {'data': data}
-
- def delete(self, prefab_id):
- """Delete this Prefab."""
- prefab = PrefabModel.from_id(prefab_id)
-
- prefab.check_exists()
- prefab.check_user_access(current_user['sub'])
-
- old_object = prefab.delete()
-
- data = PrefabSchema().dump(old_object)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the PUT operation on a prefab.
- """
- prefab = fields.Nested(PrefabSchema, required=True)
diff --git a/opendc-web/opendc-web-api/opendc/api/projects.py b/opendc-web/opendc-web-api/opendc/api/projects.py
deleted file mode 100644
index 2b47c12e..00000000
--- a/opendc-web/opendc-web-api/opendc/api/projects.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from datetime import datetime
-from flask import request
-from flask_restful import Resource
-from marshmallow import Schema, fields
-
-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
-
-
-class ProjectList(Resource):
- """
- Resource representing the list of projects available to a user.
- """
- method_decorators = [requires_auth]
-
- def get(self):
- """Get the authorized projects of the user"""
- user_id = current_user['sub']
- projects = ProjectModel.get_for_user(user_id)
- data = ProjectSchema().dump(projects, many=True)
- return {'data': data}
-
- def post(self):
- """Create a new project, and return that new project."""
- user_id = current_user['sub']
-
- schema = Project.PutSchema()
- result = schema.load(request.json)
-
- topology = Topology({'name': 'Default topology', 'rooms': []})
- topology.insert()
-
- project = ProjectModel(result['project'])
- 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'}])
- project.insert()
-
- topology.set_property('projectId', project.get_id())
- topology.update()
-
- data = ProjectSchema().dump(project.obj)
- return {'data': data}
-
-
-class Project(Resource):
- """
- Resource representing a single project.
- """
- method_decorators = [requires_auth]
-
- def get(self, project_id):
- """Get this Project."""
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], False)
-
- data = ProjectSchema().dump(project.obj)
- return {'data': data}
-
- def put(self, project_id):
- """Update a project's name."""
- schema = Project.PutSchema()
- result = schema.load(request.json)
-
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], True)
-
- project.set_property('name', result['project']['name'])
- project.set_property('datetimeLastEdited', datetime.now())
- project.update()
-
- data = ProjectSchema().dump(project.obj)
- return {'data': data}
-
- def delete(self, project_id):
- """Delete this Project."""
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], True)
-
- for topology_id in project.obj['topologyIds']:
- topology = Topology.from_id(topology_id)
- topology.delete()
-
- for portfolio_id in project.obj['portfolioIds']:
- portfolio = Portfolio.from_id(portfolio_id)
- portfolio.delete()
-
- old_object = project.delete()
- data = ProjectSchema().dump(old_object)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the PUT operation on a project.
- """
- project = fields.Nested(ProjectSchema, required=True)
-
-
-class ProjectTopologies(Resource):
- """
- Resource representing the topologies of a project.
- """
- method_decorators = [requires_auth]
-
- def get(self, project_id):
- """Get all topologies belonging to the project."""
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], True)
-
- topologies = Topology.get_for_project(project_id)
- data = TopologySchema().dump(topologies, many=True)
-
- return {'data': data}
-
- def post(self, project_id):
- """Add a new Topology to the specified project and return it"""
- schema = ProjectTopologies.PutSchema()
- result = schema.load(request.json)
-
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], True)
-
- topology = Topology({
- 'projectId': project.get_id(),
- 'name': result['topology']['name'],
- 'rooms': result['topology']['rooms'],
- })
-
- topology.insert()
-
- project.obj['topologyIds'].append(topology.get_id())
- project.set_property('datetimeLastEdited', datetime.now())
- project.update()
-
- data = TopologySchema().dump(topology.obj)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the PUT operation on a project topology.
- """
- topology = fields.Nested(TopologySchema, required=True)
-
-
-class ProjectPortfolios(Resource):
- """
- Resource representing the portfolios of a project.
- """
- method_decorators = [requires_auth]
-
- def get(self, project_id):
- """Get all portfolios belonging to the project."""
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], True)
-
- portfolios = Portfolio.get_for_project(project_id)
- data = PortfolioSchema().dump(portfolios, many=True)
-
- return {'data': data}
-
- def post(self, project_id):
- """Add a new Portfolio for this Project."""
- schema = ProjectPortfolios.PutSchema()
- result = schema.load(request.json)
-
- project = ProjectModel.from_id(project_id)
-
- project.check_exists()
- project.check_user_access(current_user['sub'], True)
-
- portfolio = Portfolio(result['portfolio'])
-
- portfolio.set_property('projectId', project.get_id())
- portfolio.set_property('scenarioIds', [])
-
- portfolio.insert()
-
- project.obj['portfolioIds'].append(portfolio.get_id())
- project.update()
-
- data = PortfolioSchema().dump(portfolio.obj)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the PUT operation on a project portfolio.
- """
- portfolio = fields.Nested(PortfolioSchema, required=True)
diff --git a/opendc-web/opendc-web-api/opendc/api/scenarios.py b/opendc-web/opendc-web-api/opendc/api/scenarios.py
deleted file mode 100644
index eacb0b49..00000000
--- a/opendc-web/opendc-web-api/opendc/api/scenarios.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from flask import request
-from flask_restful import Resource
-from marshmallow import Schema, fields
-
-from opendc.models.scenario import Scenario as ScenarioModel, ScenarioSchema
-from opendc.models.portfolio import Portfolio
-from opendc.exts import current_user, requires_auth, has_scope
-
-
-class Scenario(Resource):
- """
- A Scenario resource.
- """
- method_decorators = [requires_auth]
-
- def get(self, scenario_id):
- """Get scenario by identifier."""
- scenario = ScenarioModel.from_id(scenario_id)
- scenario.check_exists()
-
- # Users with scope runner can access all scenarios
- if not has_scope('runner'):
- scenario.check_user_access(current_user['sub'], False)
-
- data = ScenarioSchema().dump(scenario.obj)
- return {'data': data}
-
- def put(self, scenario_id):
- """Update this Scenarios name."""
- schema = Scenario.PutSchema()
- result = schema.load(request.json)
-
- scenario = ScenarioModel.from_id(scenario_id)
-
- scenario.check_exists()
- scenario.check_user_access(current_user['sub'], True)
-
- scenario.set_property('name', result['scenario']['name'])
-
- scenario.update()
- data = ScenarioSchema().dump(scenario.obj)
- return {'data': data}
-
- def delete(self, scenario_id):
- """Delete this Scenario."""
- scenario = ScenarioModel.from_id(scenario_id)
- scenario.check_exists()
- scenario.check_user_access(current_user['sub'], True)
-
- scenario_id = scenario.get_id()
-
- portfolio = Portfolio.from_id(scenario.obj['portfolioId'])
- portfolio.check_exists()
- if scenario_id in portfolio.obj['scenarioIds']:
- portfolio.obj['scenarioIds'].remove(scenario_id)
- portfolio.update()
-
- old_object = scenario.delete()
- data = ScenarioSchema().dump(old_object)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the put operation.
- """
- scenario = fields.Nested(ScenarioSchema, required=True)
diff --git a/opendc-web/opendc-web-api/opendc/api/schedulers.py b/opendc-web/opendc-web-api/opendc/api/schedulers.py
deleted file mode 100644
index b00d8c31..00000000
--- a/opendc-web/opendc-web-api/opendc/api/schedulers.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-
-from flask_restful import Resource
-from opendc.exts import requires_auth
-
-SCHEDULERS = [
- 'mem',
- 'mem-inv',
- 'core-mem',
- 'core-mem-inv',
- 'active-servers',
- 'active-servers-inv',
- 'provisioned-cores',
- 'provisioned-cores-inv',
- 'random'
-]
-
-
-class SchedulerList(Resource):
- """
- Resource for the list of schedulers to pick from.
- """
- method_decorators = [requires_auth]
-
- def get(self):
- """Get all available Traces."""
- return {'data': [{'name': name} for name in SCHEDULERS]}
diff --git a/opendc-web/opendc-web-api/opendc/api/topologies.py b/opendc-web/opendc-web-api/opendc/api/topologies.py
deleted file mode 100644
index c0b2e7ee..00000000
--- a/opendc-web/opendc-web-api/opendc/api/topologies.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from datetime import datetime
-
-from flask import request
-from flask_restful import Resource
-from marshmallow import Schema, fields
-
-from opendc.models.project import Project
-from opendc.models.topology import Topology as TopologyModel, TopologySchema
-from opendc.exts import current_user, requires_auth, has_scope
-
-
-class Topology(Resource):
- """
- Resource representing a single topology.
- """
- method_decorators = [requires_auth]
-
- def get(self, topology_id):
- """
- Get a single topology.
- """
- topology = TopologyModel.from_id(topology_id)
- topology.check_exists()
-
- # Users with scope runner can access all topologies
- if not has_scope('runner'):
- topology.check_user_access(current_user['sub'], False)
-
- data = TopologySchema().dump(topology.obj)
- return {'data': data}
-
- def put(self, topology_id):
- """
- Replace the topology.
- """
- topology = TopologyModel.from_id(topology_id)
-
- schema = Topology.PutSchema()
- result = schema.load(request.json)
-
- topology.check_exists()
- topology.check_user_access(current_user['sub'], True)
-
- topology.set_property('name', result['topology']['name'])
- topology.set_property('rooms', result['topology']['rooms'])
- topology.set_property('datetimeLastEdited', datetime.now())
-
- topology.update()
- data = TopologySchema().dump(topology.obj)
- return {'data': data}
-
- def delete(self, topology_id):
- """
- Delete a topology.
- """
- topology = TopologyModel.from_id(topology_id)
-
- topology.check_exists()
- topology.check_user_access(current_user['sub'], True)
-
- topology_id = topology.get_id()
-
- project = Project.from_id(topology.obj['projectId'])
- project.check_exists()
- if topology_id in project.obj['topologyIds']:
- project.obj['topologyIds'].remove(topology_id)
- project.update()
-
- old_object = topology.delete()
- data = TopologySchema().dump(old_object)
- return {'data': data}
-
- class PutSchema(Schema):
- """
- Schema for the PUT operation on a topology.
- """
- topology = fields.Nested(TopologySchema, required=True)
diff --git a/opendc-web/opendc-web-api/opendc/api/traces.py b/opendc-web/opendc-web-api/opendc/api/traces.py
deleted file mode 100644
index 6be8c5e5..00000000
--- a/opendc-web/opendc-web-api/opendc/api/traces.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (c) 2021 AtLarge Research
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-from flask_restful import Resource
-
-from opendc.exts import requires_auth
-from opendc.models.trace import Trace as TraceModel, TraceSchema
-
-
-class TraceList(Resource):
- """
- Resource for the list of traces to pick from.
- """
- method_decorators = [requires_auth]
-
- def get(self):
- """Get all available Traces."""
- traces = TraceModel.get_all()
- data = TraceSchema().dump(traces.obj, many=True)
- return {'data': data}
-
-
-class Trace(Resource):
- """
- Resource representing a single trace.
- """
- method_decorators = [requires_auth]
-
- def get(self, trace_id):
- """Get trace information by identifier."""
- trace = TraceModel.from_id(trace_id)
- trace.check_exists()
- data = TraceSchema().dump(trace.obj)
- return {'data': data}