
Use oslo.rootwrap to replace the default root_helper sudo. Change-Id: I5875cd647a4cc4f60f3058a98ea8a829cf056c43 Implements: blueprint astara-rootwrap
156 lines
4.6 KiB
Python
156 lines
4.6 KiB
Python
# Copyright 2014 DreamHost, LLC
|
|
#
|
|
# Author: DreamHost, LLC
|
|
#
|
|
# 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.
|
|
|
|
|
|
"""
|
|
Blueprint for the "system" portion of the version 1 of the API.
|
|
"""
|
|
from flask import Response
|
|
from flask import abort, request
|
|
from dogpile.cache import make_region
|
|
|
|
from astara_router import models
|
|
from astara_router import utils
|
|
from astara_router import settings
|
|
from astara_router.manager import manager
|
|
|
|
blueprint = utils.blueprint_factory(__name__)
|
|
|
|
# Managed by _get_cache()
|
|
_cache = None
|
|
|
|
|
|
ADVANCED_SERVICES_KEY = 'services'
|
|
|
|
|
|
def _get_cache():
|
|
global _cache
|
|
if _cache is None:
|
|
_cache = make_region().configure(
|
|
'dogpile.cache.dbm',
|
|
arguments={
|
|
"filename": "/tmp/astara-state"
|
|
}
|
|
)
|
|
return _cache
|
|
|
|
|
|
@blueprint.route('/interface/<ifname>')
|
|
@utils.json_response
|
|
def get_interface(ifname):
|
|
'''
|
|
Show interface parameters given an interface name.
|
|
For example ge1, ge2 for generic ethernet
|
|
'''
|
|
return dict(interface=manager.router.get_interface(ifname))
|
|
|
|
|
|
@blueprint.route('/interfaces')
|
|
@utils.json_response
|
|
def get_interfaces():
|
|
'''
|
|
Show all interfaces and parameters
|
|
'''
|
|
return dict(interfaces=manager.router.get_interfaces())
|
|
|
|
|
|
@blueprint.route('/config', methods=['GET'])
|
|
@utils.json_response
|
|
def get_configuration():
|
|
"""Return the current router configuration."""
|
|
return dict(configuration=manager.config)
|
|
|
|
|
|
@blueprint.route('/config', methods=['PUT'])
|
|
@utils.json_response
|
|
def put_configuration():
|
|
if request.content_type != 'application/json':
|
|
abort(415)
|
|
|
|
try:
|
|
system_config_candidate = models.SystemConfiguration(request.json)
|
|
except ValueError, e:
|
|
return Response(
|
|
'The system config failed to deserialize.\n' + str(e),
|
|
status=422)
|
|
|
|
errors = system_config_candidate.validate()
|
|
if errors:
|
|
return Response(
|
|
'The config failed to validate.\n' + '\n'.join(errors),
|
|
status=422)
|
|
|
|
# Config requests to a router appliance will always contain a default ASN,
|
|
# so we can key on that for now. Later on we need to move router stuff
|
|
# to the extensible list of things the appliance can handle
|
|
if request.json.get('asn'):
|
|
try:
|
|
router_config_candidate = models.RouterConfiguration(request.json)
|
|
except ValueError, e:
|
|
return Response(
|
|
'The router config failed to deserialize.\n' + str(e),
|
|
status=422)
|
|
|
|
errors = router_config_candidate.validate()
|
|
if errors:
|
|
return Response(
|
|
'The config failed to validate.\n' + '\n'.join(errors),
|
|
status=422)
|
|
else:
|
|
router_config_candidate = None
|
|
|
|
if router_config_candidate:
|
|
advanced_service_configs = [router_config_candidate]
|
|
else:
|
|
advanced_service_configs = []
|
|
|
|
advanced_services = request.json.get(ADVANCED_SERVICES_KEY, {})
|
|
for svc in advanced_services.keys():
|
|
if svc not in settings.ENABLED_SERVICES:
|
|
return Response(
|
|
'This appliance cannot service requested advanced '
|
|
'service: %s' % svc, status=400)
|
|
|
|
for svc in settings.ENABLED_SERVICES:
|
|
if not advanced_services.get(svc):
|
|
continue
|
|
|
|
config_model = models.get_config_model(service=svc)
|
|
if not config_model:
|
|
continue
|
|
|
|
try:
|
|
svc_config_candidate = config_model(advanced_services.get(svc))
|
|
except ValueError, e:
|
|
return Response(
|
|
'The %s config failed to deserialize.\n' + str(e) %
|
|
config_model.service_name, status=422)
|
|
|
|
errors = svc_config_candidate.validate()
|
|
if errors:
|
|
return Response(
|
|
'The %s config failed to validate.\n' + '\n'.join(errors),
|
|
config_model.service_name, status=422)
|
|
|
|
advanced_service_configs.append(svc_config_candidate)
|
|
|
|
manager.update_config(
|
|
system_config=system_config_candidate,
|
|
service_configs=advanced_service_configs,
|
|
cache=_get_cache())
|
|
|
|
return dict(configuration=manager.config)
|