diff options
Diffstat (limited to 'app/app/config_binding_service')
-rw-r--r-- | app/app/config_binding_service/__init__.py | 46 | ||||
-rw-r--r-- | app/app/config_binding_service/client.py | 297 | ||||
-rw-r--r-- | app/app/config_binding_service/controller.py | 108 | ||||
-rw-r--r-- | app/app/config_binding_service/logging.py | 204 | ||||
-rw-r--r-- | app/app/config_binding_service/openapi.yaml | 112 |
5 files changed, 0 insertions, 767 deletions
diff --git a/app/app/config_binding_service/__init__.py b/app/app/config_binding_service/__init__.py deleted file mode 100644 index 306a762..0000000 --- a/app/app/config_binding_service/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -# ============LICENSE_START======================================================= -# Copyright (c) 2017-2019 AT&T Intellectual Property. All 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. -# ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - -import os -import connexion - - -class BadEnviornmentENVNotFound(Exception): - """ - Specific exception to be raised when a required ENV varaible is missing - """ - pass - - -def get_consul_uri(): - """ - This method waterfalls reads an envioronmental variable called CONSUL_HOST - If that doesn't work, it raises an Exception - """ - if "CONSUL_HOST" in os.environ: - # WARNING! TODO! Currently the env file does not include the port. - # But some other people think that the port should be a part of that. - # For now, I'm hardcoding 8500 until this gets resolved. - return "http://{0}:{1}".format(os.environ["CONSUL_HOST"], 8500) - else: - raise BadEnviornmentENVNotFound("CONSUL_HOST") - - -# this has to be here due to circular dependency -app = connexion.App(__name__, specification_dir='.') -app.add_api('openapi.yaml', arguments={'title': 'Config Binding Service'}) diff --git a/app/app/config_binding_service/client.py b/app/app/config_binding_service/client.py deleted file mode 100644 index c6a6753..0000000 --- a/app/app/config_binding_service/client.py +++ /dev/null @@ -1,297 +0,0 @@ -# ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All 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. -# ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - -import re -from functools import partial, reduce -import base64 -import copy -import json -import requests -import six -from config_binding_service import get_consul_uri -from config_binding_service.logging import utc, metrics - - -CONSUL = get_consul_uri() - -template_match_rels = re.compile("\{{2}([^\}\{]*)\}{2}") -template_match_dmaap = re.compile("<{2}([^><]*)>{2}") - -### -# Cusom Exception -### - - -class CantGetConfig(Exception): - """ - Represents an exception where a required key in consul isn't there - """ - - def __init__(self, code, response): - self.code = code - self.response = response - - -class BadRequest(Exception): - """ - Exception to be raised when the user tried to do something they shouldn't - """ - - def __init__(self, response): - self.code = 400 - self.response = response - - -### -# Private Functions -### - - -def _consul_get_all_as_transaction(service_component_name, raw_request, xer): - """ - Use Consul's transaction API to get all keys of the form service_component_name:* - Return a dict with all the values decoded - """ - payload = [ - { - "KV": { - "Verb": "get-tree", - "Key": service_component_name, - } - }] - - bts = utc() - response = requests.put("{0}/v1/txn".format(CONSUL), json=payload) - metrics(raw_request, bts, xer, "Consul", "/v1/txn".format(service_component_name), response.status_code, __name__, msg="Retrieving Consul transaction for all keys for {0}".format(service_component_name)) - - try: - response.raise_for_status() - except requests.exceptions.HTTPError as exc: - raise CantGetConfig(exc.response.status_code, exc.response.text) - - result = json.loads(response.text)['Results'] - - new_res = {} - for res in result: - key = res["KV"]["Key"] - val = base64.b64decode(res["KV"]["Value"]).decode("utf-8") - try: - new_res[key] = json.loads(val) - except json.decoder.JSONDecodeError: - new_res[key] = "INVALID JSON" # TODO, should we just include the original value somehow? - - if service_component_name not in new_res: - raise CantGetConfig(404, "") - - return new_res - - -def _get_config_rels_dmaap(service_component_name, raw_request, xer): - allk = _consul_get_all_as_transaction(service_component_name, raw_request, xer) - config = allk[service_component_name] - rels = allk.get(service_component_name + ":rels", []) - dmaap = allk.get(service_component_name + ":dmaap", {}) - return config, rels, dmaap - - -def _get_connection_info_from_consul(service_component_name): - """ - Call consul's catalog - TODO: currently assumes there is only one service - - DEPRECATION NOTE: - This function existed when DCAE was using Consul to resolve service component's connection information. - This relied on a "rels" key and a Cloudify relationship plugin to set up the magic. - The consensous is that this feature is no longer used. - This functionality is very likely deprecated by Kubernetes service discovery mechanism, and DMaaP. - - This function also includes logic related to CDAP, which is also likely deprecated. - - This code shall remain here for now but is at risk of being deleted in a future release. - """ - # Note: there should be a metrics log here, but see the deprecation note above; this function is due to be deleted. - res = requests.get("{0}/v1/catalog/service/{1}".format(CONSUL, service_component_name)) - res.raise_for_status() - services = res.json() - if services == []: - return None # later will get filtered out - ip_addr = services[0]["ServiceAddress"] - port = services[0]["ServicePort"] - - if "cdap_app" in service_component_name: - redirectish_url = "http://{0}:{1}/application/{2}".format(ip_addr, port, service_component_name) - res = requests.get(redirectish_url) - res.raise_for_status() - details = res.json() - # Pick out the details to expose to the component developers. These keys come from the broker API - return {key: details[key] for key in ["connectionurl", "serviceendpoints"]} - return "{0}:{1}".format(ip_addr, port) - - -def _replace_rels_template(rels, template_identifier): - """ - The magic. Replaces a template identifier {{...}} with the entrie(s) from the rels keys - NOTE: There was a discussion over whether the CBS should treat {{}} as invalid. Mike asked that - it resolve to the empty list. So, it does resolve it to empty list. - """ - returnl = [] - for rel in rels: - if template_identifier in rel and template_identifier != "": - returnl.append(rel) - # returnl now contains a list of DNS names (possible empty), now resolve them (or not if they are not regustered) - return list(filter(lambda x: x is not None, map(_get_connection_info_from_consul, returnl))) - - -def _replace_dmaap_template(dmaap, template_identifier): - """ - This one liner could have been just put inline in the caller but maybe this will get more complex in future - Talked to Mike, default value if key is not found in dmaap key should be {} - """ - return {} if (template_identifier not in dmaap or template_identifier == "<<>>") else dmaap[template_identifier] - - -def _replace_value(v, rels, dmaap): - """ - Takes a value v that was some value in the templatized configuration, determines whether it needs replacement (either {{}} or <<>>), and if so, replaces it. - Otherwise just returns v - - implementation notes: - - the split below sees if we have v = x,y,z... so we can support {{x,y,z,....}} - - the lambda is because we can't fold operators in Python, wanted fold(+, L) where + when applied to lists in python is list concatenation - """ - if isinstance(v, six.string_types): # do not try to replace anything that is not a string - match_on_rels = re.match(template_match_rels, v) - if match_on_rels: - # now holds just x,.. of {{x,...}} - template_identifier = match_on_rels.groups()[0].strip() - rtpartial = partial(_replace_rels_template, rels) - return reduce(lambda a, b: a + b, map(rtpartial, template_identifier.split(",")), []) - match_on_dmaap = re.match(template_match_dmaap, v) - if match_on_dmaap: - template_identifier = match_on_dmaap.groups()[0].strip() - """ - Here is what Mike said: - 1) want simple replacement of "<< >>" with dmaap key value - 2) never need to support <<f1,f2>> whereas we do support {{sct1,sct2}} - The consequence is that if you give the CBS a dmaap key like {"foo" : {...}} you are going to get back {...}, but rels always returns [...]. - So now component developers have to possible handle dicts and [], and we have to communicate that to them - """ - return _replace_dmaap_template(dmaap, template_identifier) - return v # was not a match or was not a string, return value as is - - -def _recurse(config, rels, dmaap): - """ - Recurse throug a configuration, or recursively a sub elemebt of it. - If it's a dict: recurse over all the values - If it's a list: recurse over all the values - If it's a string: return the replacement - If none of the above, just return the item. - """ - if isinstance(config, list): - return [_recurse(item, rels, dmaap) for item in config] - if isinstance(config, dict): - for key in config: - config[key] = _recurse(config[key], rels, dmaap) - return config - if isinstance(config, six.string_types): - return _replace_value(config, rels, dmaap) - # not a dict, not a list, not a string, nothing to do. - return config - - -######### -# PUBLIC API -######### - - -def resolve(service_component_name, raw_request, xer): - """ - Return the bound config of service_component_name - - raw_request and xer are needed to form the correct metrics log - """ - config, rels, dmaap = _get_config_rels_dmaap(service_component_name, raw_request, xer) - return _recurse(config, rels, dmaap) - - -def resolve_override(config, rels=[], dmaap={}): - """ - Explicitly take in a config, rels, dmaap and try to resolve it. - Useful for testing where you dont want to put the test values in consul - """ - # use deepcopy to make sure that config is not touched - return _recurse(copy.deepcopy(config), rels, dmaap) - - -def resolve_all(service_component_name, raw_request, xer): - """ - Return config, policies, and any other k such that service_component_name:k exists (other than :dmaap and :rels) - - raw_request and xer are needed to form the correct metrics log - """ - allk = _consul_get_all_as_transaction(service_component_name, raw_request, xer) - returnk = {} - - # replace the config with the resolved config - returnk["config"] = resolve_override(allk[service_component_name], - allk.get("{0}:rels".format(service_component_name), []), - allk.get("{0}:dmaap".format(service_component_name), {})) - - # concatenate the items - for k in allk: - if "policies" in k: - if "policies" not in returnk: - returnk["policies"] = {} - returnk["policies"]["event"] = {} - returnk["policies"]["items"] = [] - - if k.endswith(":policies/event"): - returnk["policies"]["event"] = allk[k] - elif ":policies/items" in k: - returnk["policies"]["items"].append(allk[k]) - else: - if not(k == service_component_name or k.endswith(":rels") or k.endswith(":dmaap")): - # this would blow up if you had a key in consul without a : but this shouldnt happen - suffix = k.split(":")[1] - returnk[suffix] = allk[k] - - return returnk - - -def get_key(key, service_component_name, raw_request, xer): - """ - Try to fetch a key k from Consul of the form service_component_name:k - - raw_request and xer are needed to form the correct metrics log - """ - if key == "policies": - raise BadRequest( - ":policies is a complex folder and should be retrieved using the service_component_all API") - - bts = utc() - path = "v1/kv/{0}:{1}".format(service_component_name, key) - response = requests.get("{0}/{1}".format(CONSUL, path)) - metrics(raw_request, bts, xer, "Consul", path, response.status_code, __name__, msg="Retrieving single Consul key {0} for {1}".format(key, service_component_name)) - - try: - response.raise_for_status() - except requests.exceptions.HTTPError as exc: - raise CantGetConfig(exc.response.status_code, exc.response.text) - rest = json.loads(response.text)[0] - return json.loads(base64.b64decode(rest["Value"]).decode("utf-8")) diff --git a/app/app/config_binding_service/controller.py b/app/app/config_binding_service/controller.py deleted file mode 100644 index c2eb21c..0000000 --- a/app/app/config_binding_service/controller.py +++ /dev/null @@ -1,108 +0,0 @@ -# ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All 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. -# ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - -import json -import requests -import connexion -import uuid -from flask import Response -from config_binding_service import client, get_consul_uri -from config_binding_service.logging import audit, utc, error, metrics - - -def _get_helper(json_expecting_func, **kwargs): - """ - Helper function used by several functions below - """ - try: - payload = json_expecting_func(**kwargs) - response, status_code, mimetype = json.dumps(payload), 200, "application/json" - except client.BadRequest as exc: - response, status_code, mimetype = exc.response, exc.code, "text/plain" - except client.CantGetConfig as exc: - response, status_code, mimetype = exc.response, exc.code, "text/plain" - except Exception: - response, status_code, mimetype = "Unknown error", 500, "text/plain" - return response, status_code, mimetype - - -def _get_or_generate_xer(raw_request): - """get or generate the transaction id""" - xer = raw_request.headers.get("x-onap-requestid", None) - if xer is None: - # some components are still using the old name - xer = raw_request.headers.get("x-ecomp-requestid", None) - if xer is None: - # the user did NOT supply a request id, generate one - xer = str(uuid.uuid4()) - return xer - - -def bind_all(service_component_name): - """ - Get all the keys in Consul for this SCN, and bind the config - """ - xer = _get_or_generate_xer(connexion.request) - bts = utc() - response, status_code, mimetype = _get_helper(client.resolve_all, service_component_name=service_component_name, raw_request=connexion.request, xer=xer) - audit(connexion.request, bts, xer, status_code, __name__, "called for component {0}".format(service_component_name)) - # Even though some older components might be using the ecomp name, we return the proper one - return Response(response=response, status=status_code, mimetype=mimetype, headers={"x-onap-requestid": xer}) - - -def bind_config_for_scn(service_component_name): - """ - Bind just the config for this SCN - """ - xer = _get_or_generate_xer(connexion.request) - bts = utc() - response, status_code, mimetype = _get_helper(client.resolve, service_component_name=service_component_name, raw_request=connexion.request, xer=xer) - audit(connexion.request, bts, xer, status_code, __name__, "called for component {0}".format(service_component_name)) - return Response(response=response, status=status_code, mimetype=mimetype, headers={"x-onap-requestid": xer}) - - -def get_key(key, service_component_name): - """ - Get a single key k of the form service_component_name:k from Consul. - Should not be used and will return a BAD REQUEST for k=policies because it's a complex object - """ - xer = _get_or_generate_xer(connexion.request) - bts = utc() - response, status_code, mimetype = _get_helper(client.get_key, key=key, service_component_name=service_component_name, raw_request=connexion.request, xer=xer) - audit(connexion.request, bts, xer, status_code, __name__, "called for component {0}".format(service_component_name)) - return Response(response=response, status=status_code, mimetype=mimetype, headers={"x-onap-requestid": xer}) - - -def healthcheck(): - """ - CBS Healthcheck - """ - xer = _get_or_generate_xer(connexion.request) - path = "v1/catalog/service/config_binding_service" - bts = utc() - res = requests.get("{0}/{1}".format(get_consul_uri(), path)) - status = res.status_code - if status == 200: - msg = "CBS is alive and Consul connection OK" - else: - msg = "CBS is alive but cannot reach Consul" - # treating this as a WARN because this could be a temporary network glitch. Also per EELF guidelines this is a 200 ecode (availability) - error(connexion.request, xer, "WARN", 200, tgt_entity="Consul", tgt_path="/v1/catalog/service/config_binding_service", msg=msg) - metrics(connexion.request, bts, xer, "Consul", path, res.status_code, __name__, msg="Checking Consul connectivity during CBS healthcheck, {0}".format(msg)) - audit(connexion.request, bts, xer, status, __name__, msg=msg) - return Response(response=msg, status=status) diff --git a/app/app/config_binding_service/logging.py b/app/app/config_binding_service/logging.py deleted file mode 100644 index b6275a7..0000000 --- a/app/app/config_binding_service/logging.py +++ /dev/null @@ -1,204 +0,0 @@ -# ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All 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. -# ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - -from logging import getLogger, Formatter -from logging.handlers import RotatingFileHandler -from os import makedirs -import datetime - - -_AUDIT_LOGGER = getLogger("defaultlogger") -_ERROR_LOGGER = getLogger("defaultlogger") -_METRICS_LOGGER = getLogger("defaultlogger") - - -def _create_logger(name, logfile): - """ - Create a RotatingFileHandler and a streamhandler for stdout - https://docs.python.org/3/library/logging.handlers.html - what's with the non-pythonic naming in these stdlib methods? Shameful. - """ - logger = getLogger(name) - file_handler = RotatingFileHandler(logfile, - maxBytes=10000000, backupCount=2) # 10 meg with one backup.. - formatter = Formatter('%(message)s') - file_handler.setFormatter(formatter) - logger.setLevel("DEBUG") - logger.addHandler(file_handler) - return logger - - -def create_loggers(): - """ - Public method to set the global logger, launched from Run - This is *not* launched during unit testing, so unit tests do not create/write log files - """ - makedirs("/opt/logs", exist_ok=True) - - # create the audit log - aud_file = "/opt/logs/audit.log" - open(aud_file, 'a').close() # this is like "touch" - global _AUDIT_LOGGER - _AUDIT_LOGGER = _create_logger("config_binding_service_audit", aud_file) - - # create the error log - err_file = "/opt/logs/error.log" - open(err_file, 'a').close() # this is like "touch" - global _ERROR_LOGGER - _ERROR_LOGGER = _create_logger("config_binding_service_error", err_file) - - # create the metrics log - met_file = "/opt/logs/metrics.log" - open(met_file, 'a').close() # this is like "touch" - global _METRICS_LOGGER - _METRICS_LOGGER = _create_logger("config_binding_service_metrics", met_file) - - -def utc(): - """gets current time in utc""" - return datetime.datetime.utcnow() - - -def audit(raw_request, bts, xer, rcode, calling_mod, msg="n/a"): - """ - write an EELF audit record per https://wiki.onap.org/download/attachments/1015849/ONAP%20application%20logging%20guidelines.pdf?api=v2 - %The audit fields implemented: - - 1 BeginTimestamp Implemented (bts) - 2 EndTimestamp Auto Injected when this is called - 3 RequestID Implemented (xer) - 5 threadId n/a - 7 serviceName Implemented (from Req) - 9 StatusCode Auto injected based on rcode - 10 ResponseCode Implemented (rcode) - 13 Category log level - all audit records are INFO. - 15 Server IP address Implemented (from Req) - 16 ElapsedTime Auto Injected (milliseconds) - 17 Server This is running in a Docker container so this is not applicable, my HOSTNAME is always "config_binding_service" - 18 ClientIPaddress Implemented (from Req) - 19 class name Implemented (mod), though docs say OOP, I am using the python module here - 20 Unused ...implemented.... - 21-25 Custom n/a - 26 detailMessage Implemented (msg) - - Not implemented - 4 serviceInstanceID - ? - 6 physical/virtual server name (Optional) - 8 PartnerName - nothing in the request tells me this - 11 Response Description - the CBS follows standard HTTP error codes so look them up - 12 instanceUUID - Optional - 14 Severity (Optional) - """ - ets = utc() - - _AUDIT_LOGGER.info("{bts}|{ets}|{xer}||n/a||{path}||{status}|{rcode}|||INFO||{servip}|{et}|config_binding_service|{clientip}|{calling_mod}|||||||{msg}".format( - bts=bts.isoformat(), - ets=ets.isoformat(), - xer=xer, rcode=rcode, - path=raw_request.path.split("/")[1], - status="COMPLETE" if rcode < 400 else "ERROR", - servip=raw_request.host.split(":")[0], - et=int((ets - bts).microseconds / 1000), # supposed to be in milleseconds - clientip=raw_request.remote_addr, - calling_mod=calling_mod, msg=msg - )) - - -def error(raw_request, xer, severity, ecode, tgt_entity="n/a", tgt_path="n/a", msg="n/a", adv_msg="n/a"): - """ - write an EELF error record per - the error fields implemented: - - 1 Timestamp Auto Injected when this is called - 2 RequestID Implemented (xer) - 3 ThreadID n/a - 4 ServiceName Implemented (from Req) - 6 TargetEntity Implemented (tgt_entity) - 7 TargetServiceName Implemented (tgt_path)/ - 8 ErrorCategory Implemented (severity) - 9. ErrorCode Implemented (ecode) - 10 ErrorDescription Implemented (msg) - 11. detailMessage Implemented (adv_msg) - - Not implemented: - 5 PartnerName - nothing in the request tells me this - """ - ets = utc() - - _ERROR_LOGGER.error("{ets}|{xer}|n/a|{path}||{tge}|{tgp}|{sev}|{ecode}|{msg}|{amsg}".format( - ets=ets, - xer=xer, - path=raw_request.path.split("/")[1], - tge=tgt_entity, - tgp=tgt_path, - sev=severity, - ecode=ecode, - msg=msg, - amsg=adv_msg)) - - -def metrics(raw_request, bts, xer, target, target_path, rcode, calling_mod, msg="n/a"): - """ - write an EELF metrics record per https://wiki.onap.org/download/attachments/1015849/ONAP%20application%20logging%20guidelines.pdf?api=v2 - %The metrics fields implemented: - - 1 BeginTimestamp Implemented (bts) - 2 EndTimestamp Auto Injected when this is called - 3 RequestID Implemented (xer) - 5 threadId n/a - 7 serviceName Implemented (from Req) - 9 TargetEntity Implemented (target) - 10 TargetServiceName Implemented (target_path) - 11 StatusCode Implemented (based on rcode) - 12 Response Code Implemented (rcode) - 15 Category log level all metrics records are INFO. - 17 Server IP address Implemented (from Req) - 18 ElapsedTime Auto Injected (milliseconds) - 19 Server This is running in a Docker container so this is not applicable, my HOSTNAME is always "config_binding_service" - 20 ClientIPaddress Implemented (from Req) - 21 class name Implemented (mod), though docs say OOP, I am using the python module here - 22 Unused ...implemented.... - 24 TargetVirtualEntity n/a - 25-28 Custom n/a - 29 detailMessage Implemented (msg) - - Not implemented - 4 serviceInstanceID - ? - 6 physical/virtual server name (Optional) - 8 PartnerName - nothing in the request tells me this - 13 Response Description - the CBS follows standard HTTP error codes so look them up - 14 instanceUUID - Optional - 16 Severity (Optional) - 23 ProcessKey - optional - """ - ets = utc() - - _METRICS_LOGGER.info("{bts}|{ets}|{xer}||n/a||{path}||{tge}|{tgp}|{status}|{rcode}|||INFO||{servip}|{et}|config_binding_service|{clientip}|{calling_mod}|||n/a|||||{msg}".format( - bts=bts.isoformat(), - ets=ets.isoformat(), - xer=xer, - path=raw_request.path.split("/")[1], - tge=target, - tgp=target_path, - status="COMPLETE" if rcode < 400 else "ERROR", - rcode=rcode, - servip=raw_request.host.split(":")[0], - et=int((ets - bts).microseconds / 1000), # supposed to be in milleseconds - clientip=raw_request.remote_addr, - calling_mod=calling_mod, msg=msg - )) diff --git a/app/app/config_binding_service/openapi.yaml b/app/app/config_binding_service/openapi.yaml deleted file mode 100644 index bc4dd49..0000000 --- a/app/app/config_binding_service/openapi.yaml +++ /dev/null @@ -1,112 +0,0 @@ -openapi: 3.0.0 -info: - version: 2.3.0 - title: Config Binding Service -paths: - '/service_component/{service_component_name}': - parameters: - - name: service_component_name - in: path - description: >- - Service Component Name. service_component_name must be a key in - consul. - required: true - schema: - type: string - get: - description: >- - Binds the configuration for service_component_name and returns the bound - configuration as a JSON - operationId: config_binding_service.controller.bind_config_for_scn - responses: - '200': - description: OK; the bound config is returned as an object - content: - '*/*': - schema: - type: object - '404': - description: there is no configuration in Consul for this component - '/service_component_all/{service_component_name}': - parameters: - - name: service_component_name - in: path - description: >- - Service Component Name. service_component_name must be a key in - consul. - required: true - schema: - type: string - get: - description: >- - Binds the configuration for service_component_name and returns the bound - configuration, policies, and any other keys that are in Consul - operationId: config_binding_service.controller.bind_all - responses: - '200': - description: >- - OK; returns {config : ..., policies : ....., k : ...} for all other - k in Consul - content: - '*/*': - schema: - type: object - '404': - description: there is no configuration in Consul for this component - '/{key}/{service_component_name}': - parameters: - - name: key - in: path - description: >- - this endpoint tries to pull service_component_name:key; key is the key - after the colon - required: true - schema: - type: string - - name: service_component_name - in: path - description: Service Component Name. - required: true - schema: - type: string - get: - description: >- - this is an endpoint that fetches a generic service_component_name:key - out of Consul. The idea is that we don't want to tie components to - Consul directly in case we swap out the backend some day, so the CBS - abstracts Consul from clients. The structuring and weird collision of - this new API with the above is unfortunate but due to legacy concerns. - operationId: config_binding_service.controller.get_key - responses: - '200': - description: 'OK; returns service_component_name:key' - content: - '*/*': - schema: - type: object - '400': - description: >- - bad request. Currently this is only returned on :policies, which is - a complex object, and should be gotten through service_component_all - content: - '*/*': - schema: - type: string - '404': - description: key does not exist - content: - '*/*': - schema: - type: string - /healthcheck: - get: - description: >- - This is the health check endpoint. If this returns a 200, the server is - alive and consul can be reached. If not a 200, either dead, or no - connection to consul - operationId: config_binding_service.controller.healthcheck - responses: - '200': - description: Successful response - '503': - description: the config binding service cannot reach Consul |