Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ matrix:
node_js: "4.2.6"
env:
- PYTHONPATH=/home/travis/build/seecloud/availability
- AVAILABILITY_CONF=/home/travis/build/seecloud/availability/tests/ci/api/config.json
- AVAILABILITY_CONF=/home/travis/build/seecloud/availability/tests/ci/api/config.yaml
services:
- docker
install:
- wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.1.1.tar.gz -O - | tar xz
- ./elasticsearch-5.1.1/bin/elasticsearch -d
- docker build -t availability .
- docker run -d -p 127.0.0.1:5000:5000 --net=host -e "AVAILABILITY_CONF=/app/tests/ci/api/config.json" availability /app/entrypoint-api.sh
- docker run -d -p 127.0.0.1:5000:5000 --net=host -e "AVAILABILITY_CONF=/app/tests/ci/api/config.yaml" availability /app/entrypoint-api.sh
- git clone http://github.com/cybertk/abao && cd abao && git checkout 0.5.0
- npm install
- cp ../tests/ci/api/abao_hooks.js hooks.js
Expand Down
5 changes: 0 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@ Here is a simple example:
.. code-block::

{
"flask": {
"PORT": 5020,
"HOST": "0.0.0.0",
"DEBUG": false
},
"backend": {
"type": "elastic",
"connection": [{"host": "127.0.0.1", "port": 9200}]
Expand Down
5 changes: 1 addition & 4 deletions availability/api/v1/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@

import flask

from availability import config
from availability import storage


LOG = logging.getLogger("api")
LOG.setLevel(config.get_config().get("logging", {}).get("level", "INFO"))
LOG = logging.getLogger(__name__)


def get_period_interval(period):
Expand Down
34 changes: 34 additions & 0 deletions availability/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2016: Mirantis Inc.
# 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.

import flask
from oss_lib import routing

from availability.api.v1 import api
from availability.api.v1 import regions

app = flask.Flask(__name__, static_folder=None)


@app.errorhandler(404)
def not_found(error):
return flask.jsonify({"error": "Not Found"}), 404


for bp in [api, regions]:
for url_prefix, blueprint in bp.get_blueprints():
app.register_blueprint(blueprint, url_prefix="/api/v1%s" % url_prefix)

app = routing.add_routing_map(app, html_uri=None, json_uri="/")
137 changes: 46 additions & 91 deletions availability/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,113 +13,68 @@
# License for the specific language governing permissions and limitations
# under the License.

import json
import logging
import os
DEFAULT_CONF_PATH = "/etc/availability/config.yaml"

import jsonschema


CONF = None

DEFAULT_CONF = {
"flask": {
"HOST": "0.0.0.0",
"PORT": 5000,
"DEBUG": False
},
DEFAULT = {
"backend": {
"type": "elastic",
"connection": [{"host": "127.0.0.1", "port": 9200}]
"connection": [
{"host": "127.0.0.1", "port": 9200},
],
},
"regions": []
"regions": [],
"period": 60,
"connection_timeout": 1,
"read_timeout": 10,
}

CONF_SCHEMA = {
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"properties": {
"flask": {
"type": "object",
"properties": {
"PORT": {"type": "integer"},
"HOST": {"type": "string"},
"DEBUG": {"type": "boolean"}
}
SCHEMA = {
"backend": {
"type": "object",
"properties": {
"type": {"type": "string"},
"connection": {
"type": "array",
"items": {
# TODO(akscram): Here should be enum.
"type": "object",
"properties": {
"host": {"type": "string"},
"port": {"type": "integer"},
},
"required": ["host"],
"additionalProperties": False,
},
"minItems": 1,
},
},
"backend": {
"required": ["type", "connection"],
"additionalProperties": False,
},
"regions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {"type": "string"},
"connection": {
"name": {"type": "string"},
"services": {
"type": "array",
"items": {
"type": "object",
"properties": {
"host": {"type": "string"},
"port": {"type": "integer"}
"name": {"type": "string"},
"url": {"type": "string"}
},
"required": ["host"]
"required": ["name", "url"],
"additionalProperties": False,
},
"minItems": 1
}
"minItems": 1,
},
},
"required": ["type", "connection"]
},
"regions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"services": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"url": {"type": "string"}
},
"required": ["name", "url"]
},
"minItems": 1
}
}
}
"additionalProperties": False,
},
"period": {"type": "number", "minimum": 5},
"connection_timeout": {"type": "number"},
"read_timeout": {"type": "number"},
"logging": {
"type": "object",
"properties": {
"level": {"type": "string"}
}
}
},
"required": ["flask", "backend", "regions"]
"period": {"type": "number", "minimum": 5},
"connection_timeout": {"type": "number"},
"read_timeout": {"type": "number"},
}


def get_config():
"""Get cached configuration.

:returns: application config
:rtype: dict
"""
global CONF
if not CONF:
path = os.environ.get("AVAILABILITY_CONF",
"/etc/availability/config.json")
try:
config = json.load(open(path))
logging.info("Config is '%s'" % path)
jsonschema.validate(config, CONF_SCHEMA)
CONF = config
except IOError as exc:
logging.warning("Failed to load config from '%s': %s", path, exc)
CONF = DEFAULT_CONF
except jsonschema.exceptions.ValidationError as exc:
logging.error("Configuration file %s is not valid: %s", path, exc)
raise
return CONF
48 changes: 21 additions & 27 deletions availability/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,29 @@
# License for the specific language governing permissions and limitations
# under the License.

import flask
from flask_helpers import routing
import argparse

from availability.api.v1 import api
from availability.api.v1 import regions
from availability import config
from oss_lib import config


app = flask.Flask(__name__, static_folder=None)
app.config.update(config.get_config()["flask"])


@app.errorhandler(404)
def not_found(error):
return flask.jsonify({"error": "Not Found"}), 404


for bp in [api, regions]:
for url_prefix, blueprint in bp.get_blueprints():
app.register_blueprint(blueprint, url_prefix="/api/v1%s" % url_prefix)


app = routing.add_routing_map(app, html_uri=None, json_uri="/")
from availability import app
from availability import config as cfg


def main():
app.run(host=app.config.get("HOST", "0.0.0.0"),
port=app.config.get("PORT", 5000))


if __name__ == "__main__":
main()
parser = argparse.ArgumentParser()
parser.add_argument("--host",
default="0.0.0.0",
help="A host to bind development server. "
"(default 0.0.0.0)")
parser.add_argument("--port",
type=int,
default=5000,
help="A port to bind development server. "
"(default 5000)")
args = config.process_args("AVAILABILITY",
parser=parser,
default_config_path=cfg.DEFAULT_CONF_PATH,
defaults=cfg.DEFAULT,
validation_schema=cfg.SCHEMA)
app.app.config.update(config.CONF, **{"DEBUG": args.debug})
app.app.run(host=args.host, port=args.port)
8 changes: 4 additions & 4 deletions availability/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
import logging

import elasticsearch
from oss_lib import config

from availability import config
CONF = config.CONF
LOG = logging.getLogger(__name__)

LOG = logging.getLogger("storage")
LOG.setLevel(config.get_config().get("logging", {}).get("level", "INFO"))
NUMBER_OF_SHARDS = 2


Expand All @@ -32,7 +32,7 @@ def get_elasticsearch(check_availability=False):
:returns: Elasticsearch or None on failure
:rtype: elasticsearch.Elasticsearch
"""
nodes = config.get_config()["backend"]["connection"]
nodes = CONF["backend"]["connection"]
try:
es = elasticsearch.Elasticsearch(nodes)
if check_availability:
Expand Down
Loading