Merge pull request #1 from sh8121att/master

Setup API skeleton
This commit is contained in:
Anthony Lin 2017-06-06 14:54:57 -05:00 committed by GitHub
commit cee0f2abb3
10 changed files with 204 additions and 19 deletions

View File

@ -1,2 +1,4 @@
# shipyard
Directed acyclic graph controller for Kubernetes and OpenStack control plane life cycle management
## Testing 1 2 3

30
setup.py Normal file
View File

@ -0,0 +1,30 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from setuptools import setup
setup(name='shipyard_airflow',
version='0.1a1',
description='API for managing Airflow-based orchestration',
url='http://github.com/att-comdev/shipyard',
author='Anthony Lin - AT&T',
author_email='al498u@att.com',
license='Apache 2.0',
packages=['shipyard_airflow',
'shipyard_airflow.control'],
install_requires=[
'falcon',
'uwsgi>1.4'
]
)

View File

@ -11,10 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import falcon
from .base import BaseResource
class TasksResource(BaseResource):
class TaskResource(BaseResource):

View File

@ -12,18 +12,38 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import falcon
import json
from .regions import RegionsResource, RegionResource
from .base import ShipyardRequest, BaseResource
from .tasks import TasksResource
from .base import ShipyardRequest
from .middleware import AuthMiddleware, ContextMiddleware, LoggingMiddleware
def start_api(state_manager):
def start_api():
control_api = falcon.API(request_type=ShipyardRequest,
middleware=[AuthMiddleware(), ContextMiddleware(), LoggingMiddleware()])
control_api.add_route('/versions', VersionsResource())
# v1.0 of Drydock API
v1_0_routes = [
# API for managing region data
control_api.add_route('/region/{region_id}', TasksResource)
control_api.add_route('/region/{region_id}/server/{name}', TasksResource)
control_api.add_route('/region/{region_id}/service/{kind}', TasksResource)
('/regions', RegionsResource()),
('/regions/{region_id}', RegionResource()),
]
for path, res in v1_0_routes:
control_api.add_route('/api/v1.0' + path, res)
return control_api
class VersionsResource(BaseResource):
authorized_roles = ['anyone']
def on_get(self, req, resp):
resp.body = json.dumps({'v1.0': {
'path': '/api/v1.0',
'status': 'stable'
}})
resp.status = falcon.HTTP_200

View File

@ -16,6 +16,8 @@ import uuid
class BaseResource(object):
authorized_roles = []
def on_options(self, req, resp):
self_attrs = dir(self)
methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH']
@ -30,7 +32,13 @@ class BaseResource(object):
# By default, no one is authorized to use a resource
def authorize_roles(self, role_list):
authorized = set(self.authorized_roles)
applied = set(role_list)
if authorized.isdisjoint(applied):
return False
else:
return True
class ShipyardRequestContext(object):
@ -62,5 +70,5 @@ class ShipyardRequestContext(object):
def set_external_marker(self, marker):
self.external_marker = str(marker)[:32]
class ShipyardRequest(request.Request)
class ShipyardRequest(request.Request):
context_type = ShipyardRequestContext

View File

@ -11,8 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import falcon
import logging
class AuthMiddleware(object):
@ -31,7 +31,7 @@ class AuthMiddleware(object):
ctx.add_role('anyone')
# Authorization
def process_resource(self, req, resp, resource):
def process_resource(self, req, resp, resource, params):
ctx = req.context
if not resource.authorize_roles(ctx.roles):
@ -67,7 +67,22 @@ class ContextMiddleware(object):
elif requested_logging == 'INFO':
ctx.set_log_level('info')
ext_marker = req.get_header('X-Context-Marker')
ctx.set_external_marker(ext_marker if ext_marker is not None else '')
class LoggingMiddleware(object):
def __init__(self):
self.logger = logging.getLogger('shipyard.control')
def process_response(self, req, resp, resource, req_succeeded):
ctx = req.context
extra = {
'user': ctx.user,
'req_id': ctx.request_id,
'external_ctx': ctx.external_marker,
}
resp.append_header('X-Shipyard-Req', ctx.request_id)
self.logger.info("%s - %s" % (req.uri, resp.status), extra=extra)

View File

@ -0,0 +1,30 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import falcon
from .base import BaseResource
class RegionsResource(BaseResource):
authorized_roles = ['user']
def on_get(self, req, resp):
resp.status = falcon.HTTP_200
class RegionResource(BaseResource):
authorized_roles = ['user']
def on_get(self, req, resp, region_id):
resp.status = falcon.HTTP_200

48
shipyard_airflow/setup.py Normal file
View File

@ -0,0 +1,48 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from setuptools import setup
setup(name='drydock_provisioner',
version='0.1a1',
description='Bootstrapper for Kubernetes infrastructure',
url='http://github.com/att-comdev/drydock',
author='Scott Hussey - AT&T',
author_email='sh8121@att.com',
license='Apache 2.0',
packages=['drydock_provisioner',
'drydock_provisioner.objects',
'drydock_provisioner.ingester',
'drydock_provisioner.ingester.plugins',
'drydock_provisioner.statemgmt',
'drydock_provisioner.orchestrator',
'drydock_provisioner.control',
'drydock_provisioner.drivers',
'drydock_provisioner.drivers.oob',
'drydock_provisioner.drivers.oob.pyghmi_driver',
'drydock_provisioner.drivers.node',
'drydock_provisioner.drivers.node.maasdriver',
'drydock_provisioner.drivers.node.maasdriver.models',
'drydock_provisioner.control'],
install_requires=[
'PyYAML',
'pyghmi>=1.0.18',
'netaddr',
'falcon',
'oslo.versionedobjects>=1.23.0',
'requests',
'oauthlib',
'uwsgi>1.4',
]
)

View File

@ -0,0 +1,39 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import control.api as api
def start_shipyard():
# Setup root logger
logger = logging.getLogger('shipyard')
logger.setLevel('DEBUG')
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
# Specalized format for API logging
logger = logging.getLogger('shipyard.control')
logger.propagate = False
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(user)s - %(req_id)s - %(external_ctx)s - %(message)s')
ch = logging.StreamHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
return api.start_api()
shipyard = start_shipyard()