Initial commit
This commit is contained in:
commit
e7041b2ccd
25
.drone.yml
Normal file
25
.drone.yml
Normal file
@ -0,0 +1,25 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
steps:
|
||||
|
||||
- name: code-analysis
|
||||
image: aosapps/drone-sonar-plugin
|
||||
settings:
|
||||
sonar_host:
|
||||
from_secret: SONAR_HOST
|
||||
sonar_token:
|
||||
from_secret: SONAR_CODE
|
||||
|
||||
- name: kaniko
|
||||
image: banzaicloud/drone-kaniko
|
||||
settings:
|
||||
registry: registry.kmlabz.com
|
||||
repo: universalrobots/${DRONE_REPO_NAME}
|
||||
username:
|
||||
from_secret: DOCKER_USERNAME
|
||||
password:
|
||||
from_secret: DOCKER_PASSWORD
|
||||
tags:
|
||||
- latest
|
||||
- ${DRONE_BUILD_NUMBER}
|
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
*.swp
|
||||
venv
|
||||
*.pyc
|
||||
__pycache__/*
|
||||
__pycache__
|
||||
*.wpr
|
||||
*.log
|
||||
.idea
|
10
Dockerfile
Normal file
10
Dockerfile
Normal file
@ -0,0 +1,10 @@
|
||||
FROM python:3.9
|
||||
|
||||
ADD job_orchestrator_service requirements.txt /job_orchestrator_service/
|
||||
WORKDIR /job_orchestrator_service/
|
||||
|
||||
RUN pip3 install -r requirements.txt && pip3 install gunicorn
|
||||
|
||||
EXPOSE 8000
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]
|
||||
|
34
job_orchestrator_service/app.py
Normal file
34
job_orchestrator_service/app.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
from config import Config
|
||||
import sentry_sdk
|
||||
from sentry_sdk.integrations.flask import FlaskIntegration
|
||||
from flask import Flask
|
||||
|
||||
from utils import register_all_error_handlers
|
||||
|
||||
# import views
|
||||
from views import JobView
|
||||
|
||||
# Setup sentry
|
||||
|
||||
if Config.SENTRY_DSN:
|
||||
sentry_sdk.init(
|
||||
dsn=Config.SENTRY_DSN,
|
||||
integrations=[FlaskIntegration()],
|
||||
send_default_pii=True,
|
||||
release=Config.RELEASE_ID,
|
||||
environment=Config.RELEASEMODE
|
||||
)
|
||||
|
||||
# create flask app
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(Config)
|
||||
register_all_error_handlers(app)
|
||||
|
||||
# register views
|
||||
for view in [JobView]:
|
||||
view.register(app, trailing_slash=False)
|
||||
|
||||
# start debuggig if needed
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
15
job_orchestrator_service/config.py
Normal file
15
job_orchestrator_service/config.py
Normal file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
|
||||
"""
|
||||
Configuration
|
||||
"""
|
||||
|
||||
|
||||
class Config:
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY", os.urandom(12))
|
||||
CORS_ORIGINS = os.environ.get("ALLOWED_ORIGINS", "*")
|
||||
|
||||
SENTRY_DSN = os.environ.get("SENTRY_DSN")
|
||||
RELEASE_ID = os.environ.get("RELEASE_ID", "test")
|
||||
RELEASEMODE = os.environ.get("RELEASEMODE", "dev")
|
2
job_orchestrator_service/schemas/__init__.py
Normal file
2
job_orchestrator_service/schemas/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env python3
|
||||
from .job_schema import JobSchema
|
22
job_orchestrator_service/schemas/job_schema.py
Normal file
22
job_orchestrator_service/schemas/job_schema.py
Normal file
@ -0,0 +1,22 @@
|
||||
from marshmallow import Schema, fields
|
||||
from marshmallow.validate import Length
|
||||
from marshmallow import RAISE
|
||||
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
|
||||
|
||||
class ControlConfigurationSchema(Schema):
|
||||
pod_id = fields.UUID(required=False, missing=uuid.uuid4)
|
||||
robot_address = fields.Str(required=True)
|
||||
program_url = fields.Str(required=True)
|
||||
|
||||
|
||||
class JobSchema(Schema):
|
||||
id = fields.UUID(required=False, missing=uuid.uuid4)
|
||||
created_at = fields.DateTime(required=False, missing=datetime.now)
|
||||
|
||||
controllers = fields.Nested(ControlConfigurationSchema, many=True, required=True, validate=Length(min=1))
|
||||
|
||||
class Meta:
|
||||
unknown = RAISE
|
3
job_orchestrator_service/utils/__init__.py
Normal file
3
job_orchestrator_service/utils/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
from .require_decorators import json_required
|
||||
from .error_handlers import register_all_error_handlers
|
18
job_orchestrator_service/utils/error_handlers.py
Normal file
18
job_orchestrator_service/utils/error_handlers.py
Normal file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
def get_standard_error_handler(code: int):
|
||||
def error_handler(err):
|
||||
return {"msg": str(err)}, code
|
||||
|
||||
return error_handler
|
||||
|
||||
|
||||
# function to register all handlers
|
||||
|
||||
|
||||
def register_all_error_handlers(app):
|
||||
error_codes_to_override = [404, 403, 401, 405, 400, 409, 422]
|
||||
|
||||
for code in error_codes_to_override:
|
||||
app.register_error_handler(code, get_standard_error_handler(code))
|
16
job_orchestrator_service/utils/require_decorators.py
Normal file
16
job_orchestrator_service/utils/require_decorators.py
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
from flask import request, current_app, abort
|
||||
|
||||
from functools import wraps
|
||||
|
||||
|
||||
def json_required(f):
|
||||
@wraps(f)
|
||||
def call(*args, **kwargs):
|
||||
|
||||
if request.is_json:
|
||||
return f(*args, **kwargs)
|
||||
else:
|
||||
abort(400, "JSON required")
|
||||
|
||||
return call
|
3
job_orchestrator_service/views/__init__.py
Normal file
3
job_orchestrator_service/views/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
from .job_view import JobView
|
||||
|
31
job_orchestrator_service/views/job_view.py
Normal file
31
job_orchestrator_service/views/job_view.py
Normal file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
from flask import request, jsonify, current_app, abort, Response
|
||||
from flask_classful import FlaskView, route
|
||||
|
||||
from utils import json_required
|
||||
|
||||
from marshmallow.exceptions import ValidationError
|
||||
|
||||
from schemas import JobSchema
|
||||
|
||||
|
||||
class JobView(FlaskView):
|
||||
job_schema = JobSchema(many=False)
|
||||
jobs_schema = JobSchema(many=True, exclude=['controllers'])
|
||||
|
||||
def index(self):
|
||||
# List all jobs
|
||||
pass
|
||||
|
||||
def get(self, _id: str):
|
||||
# Get info about a job
|
||||
pass
|
||||
|
||||
@json_required
|
||||
def post(self):
|
||||
# Start (schedule) a job
|
||||
pass
|
||||
|
||||
def delete(self, _id: str):
|
||||
# stop a job
|
||||
pass
|
7
requirements.txt
Normal file
7
requirements.txt
Normal file
@ -0,0 +1,7 @@
|
||||
pyyaml
|
||||
|
||||
blinker
|
||||
Flask
|
||||
marshmallow
|
||||
Flask-Classful
|
||||
sentry-sdk
|
Loading…
Reference in New Issue
Block a user