shipyard/shipyard_airflow/control/service_endpoints.py
Hassan Kaous 3ac47328c3 Document staging api
The purpose of the document staging api is to provide a client of
shipyard to ingest and manipulate documents within the UCP platform

In support of the need to reach out to other services, this change
also introduces the use of keystone for service discovery and connection
to other UCP services.

Change-Id: I6fa113f8786cad2884c0b791788a4ef40cd1a6b6
2017-10-18 18:39:24 -05:00

127 lines
4.1 KiB
Python

# 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.
"""
Module to encapsulate thet endpoint lookup for the services used
by Shipyard
"""
import enum
import logging
import falcon
from keystoneauth1 import session
from keystoneauth1.identity import v3
from keystoneauth1.exceptions.auth import AuthorizationFailure
from keystoneauth1.exceptions.catalog import EndpointNotFound
from oslo_config import cfg
from shipyard_airflow.errors import AppError
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class Endpoints(enum.Enum):
"""
Enumeration of the endpoints that are served by this endpoint manager
"""
SHIPYARD = 'shipyard'
DRYDOCK = 'drydock'
ARMADA = 'armada'
DECKHAND = 'deckhand'
def _get_service_type(endpoint):
"""
Because these values should not be used until after initialization,
they cannot be directly associated with the enum. Thie method takes
the enum value and retrieves the values when accessed the first time.
:param Endpoints endpoint: The endpoint to look up
:returns: The service type value for the named endpoint
:rtype: str
:raises AppError: if not provided a valid Endpoints enumeration value
"""
if isinstance(endpoint, Endpoints):
endpoint_values = {
Endpoints.SHIPYARD: CONF.shipyard.service_type,
Endpoints.DRYDOCK: CONF.drydock.service_type,
Endpoints.ARMADA: CONF.armada.service_type,
Endpoints.DECKHAND: CONF.deckhand.service_type,
}
return endpoint_values.get(endpoint)
raise AppError(
title='Endpoint is not known',
description=(
'Shipyard is trying to reach an unknown endpoint: {}'.format(
endpoint.name
)
),
status=falcon.HTTP_500,
retry=False
)
def get_endpoint(endpoint):
"""
Wraps calls to keystone for lookup of an endpoint by service type
:param Endpoints endpoint: The endpoint to look up
:returns: The url string of the endpoint
:rtype: str
:raises AppError: if the endpoint cannot be resolved
"""
service_type = _get_service_type(endpoint)
try:
return _get_ks_session().get_endpoint(
interface='internal',
service_type=service_type)
except EndpointNotFound:
LOG.error('Could not find a public interface for %s',
endpoint.name)
raise AppError(
title='Can not access service endpoint',
description=(
'Keystone catalog has no internal endpoint for service type: '
'{}'.format(service_type)
),
status=falcon.HTTP_500,
retry=False)
def get_token():
"""
Returns the simple token string for a token acquired from keystone
"""
return _get_ks_session().get_auth_headers().get('X-Auth-Token')
def _get_ks_session():
# Establishes a keystone session
keystone_auth = {}
for attr in ('auth_url', 'password', 'project_domain_name',
'project_name', 'username', 'user_domain_name'):
keystone_auth[attr] = CONF.get('keystone_authtoken').get(attr)
try:
auth = v3.Password(**keystone_auth)
return session.Session(auth=auth)
except AuthorizationFailure as aferr:
LOG.error('Could not authorize against keystone: %s',
str(aferr))
raise AppError(
title='Could not authorize Shipyard against Keystone',
description=(
'Keystone has reqjected the authorization request by Shipyard'
),
status=falcon.HTTP_500,
retry=False
)