Travis ci integration (#267)
* Initial travis-ci integration * Format code base to PEP8
This commit is contained in:
committed by
Corey Hammerton
parent
0ac64530bf
commit
faac5fa1bc
3
.coveragerc
Normal file
3
.coveragerc
Normal file
@@ -0,0 +1,3 @@
|
||||
[report]
|
||||
exclude_lines =
|
||||
pragma: notest
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,5 +1,8 @@
|
||||
*.py[cod]
|
||||
|
||||
# Editor tmp files
|
||||
.*.sw*
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
@@ -22,6 +25,7 @@ lib64
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.cache
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
@@ -36,3 +40,6 @@ nosetests.xml
|
||||
|
||||
# PuppetDB Settings
|
||||
/settings.py
|
||||
|
||||
# Virtual Environment
|
||||
venv
|
||||
|
||||
13
.travis.yml
Normal file
13
.travis.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r requirements-test.txt
|
||||
- pip install -q coverage coveralls --use-wheel
|
||||
script: py.test --cov=puppetboard --pep8 -v
|
||||
|
||||
after_success:
|
||||
- coveralls
|
||||
2
conftest.py
Normal file
2
conftest.py
Normal file
@@ -0,0 +1,2 @@
|
||||
import puppetboard
|
||||
import test
|
||||
@@ -25,6 +25,7 @@ from puppetboard.utils import (
|
||||
jsonprint, prettyprint, Pagination
|
||||
)
|
||||
|
||||
DEFAULT_ORDER_BY = '[{"field": "start_time", "order": "desc"}]'
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -59,12 +60,14 @@ def stream_template(template_name, **context):
|
||||
rv.enable_buffering(5)
|
||||
return rv
|
||||
|
||||
|
||||
def url_for_field(field, value):
|
||||
args = request.view_args.copy()
|
||||
args.update(request.args.copy())
|
||||
args[field] = value
|
||||
return url_for(request.endpoint, **args)
|
||||
|
||||
|
||||
def environments():
|
||||
envs = get_or_abort(puppetdb.environments)
|
||||
x = []
|
||||
@@ -74,12 +77,14 @@ def environments():
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def check_env(env, envs):
|
||||
if env != '*' and env not in envs:
|
||||
abort(404)
|
||||
|
||||
app.jinja_env.globals['url_for_field'] = url_for_field
|
||||
|
||||
|
||||
@app.context_processor
|
||||
def utility_processor():
|
||||
def now(format='%m/%d/%Y %H:%M:%S'):
|
||||
@@ -345,7 +350,8 @@ def inventory(env):
|
||||
current_env=env)))
|
||||
|
||||
|
||||
@app.route('/node/<node_name>', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/node/<node_name>',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/node/<node_name>')
|
||||
def node(env, node_name):
|
||||
"""Display a dashboard for a node showing as much data as we have on that
|
||||
@@ -369,7 +375,7 @@ def node(env, node_name):
|
||||
reports = get_or_abort(puppetdb.reports,
|
||||
query=query,
|
||||
limit=app.config['REPORTS_COUNT'],
|
||||
order_by='[{"field": "start_time", "order": "desc"}]')
|
||||
order_by=DEFAULT_ORDER_BY)
|
||||
reports, reports_events = tee(reports)
|
||||
report_event_counts = {}
|
||||
|
||||
@@ -408,7 +414,8 @@ def node(env, node_name):
|
||||
current_env=env)
|
||||
|
||||
|
||||
@app.route('/reports/', defaults={'env': app.config['DEFAULT_ENVIRONMENT'], 'page': 1})
|
||||
@app.route('/reports/',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT'], 'page': 1})
|
||||
@app.route('/<env>/reports/', defaults={'page': 1})
|
||||
@app.route('/<env>/reports/page/<int:page>')
|
||||
def reports(env, page):
|
||||
@@ -441,7 +448,7 @@ def reports(env, page):
|
||||
|
||||
reports = get_or_abort(puppetdb.reports,
|
||||
query=reports_query,
|
||||
order_by='[{"field": "start_time", "order": "desc"}]',
|
||||
order_by=DEFAULT_ORDER_BY,
|
||||
**paging_args)
|
||||
total = get_or_abort(puppetdb._query,
|
||||
'reports',
|
||||
@@ -488,7 +495,8 @@ def reports(env, page):
|
||||
limit=paging_args.get('limit', total))))
|
||||
|
||||
|
||||
@app.route('/reports/<node_name>/', defaults={'env': app.config['DEFAULT_ENVIRONMENT'], 'page': 1})
|
||||
@app.route('/reports/<node_name>/',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT'], 'page': 1})
|
||||
@app.route('/<env>/reports/<node_name>', defaults={'page': 1})
|
||||
@app.route('/<env>/reports/<node_name>/page/<int:page>')
|
||||
def reports_node(env, node_name, page):
|
||||
@@ -520,7 +528,7 @@ def reports_node(env, node_name, page):
|
||||
query=query,
|
||||
limit=app.config['REPORTS_COUNT'],
|
||||
offset=(page - 1) * app.config['REPORTS_COUNT'],
|
||||
order_by='[{"field": "start_time", "order": "desc"}]')
|
||||
order_by=DEFAULT_ORDER_BY)
|
||||
total = get_or_abort(puppetdb._query,
|
||||
'reports',
|
||||
query=total_query)
|
||||
@@ -565,7 +573,8 @@ def reports_node(env, node_name, page):
|
||||
current_env=env)
|
||||
|
||||
|
||||
@app.route('/report/<node_name>/<report_id>', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/report/<node_name>/<report_id>',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/report/<node_name>/<report_id>')
|
||||
def report(env, node_name, report_id):
|
||||
"""Displays a single report including all the events associated with that
|
||||
@@ -638,7 +647,8 @@ def facts(env):
|
||||
sorted_facts_dict = sorted(facts_dict.items())
|
||||
return render_template('facts.html',
|
||||
facts_dict=sorted_facts_dict,
|
||||
facts_len=sum(map(len,facts_dict.values())) + len(facts_dict)*5,
|
||||
facts_len=(sum(map(len, facts_dict.values())) +
|
||||
len(facts_dict) * 5),
|
||||
envs=envs,
|
||||
current_env=env)
|
||||
|
||||
@@ -679,7 +689,8 @@ def fact(env, fact):
|
||||
current_env=env)))
|
||||
|
||||
|
||||
@app.route('/fact/<fact>/<value>', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/fact/<fact>/<value>',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/fact/<fact>/<value>')
|
||||
def fact_value(env, fact, value):
|
||||
"""On asking for fact/value get all nodes with that fact.
|
||||
@@ -713,7 +724,8 @@ def fact_value(env, fact, value):
|
||||
current_env=env)
|
||||
|
||||
|
||||
@app.route('/query', methods=('GET', 'POST'), defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/query', methods=('GET', 'POST'),
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/query', methods=('GET', 'POST'))
|
||||
def query(env):
|
||||
"""Allows to execute raw, user created querries against PuppetDB. This is
|
||||
@@ -777,7 +789,8 @@ def metrics(env):
|
||||
current_env=env)
|
||||
|
||||
|
||||
@app.route('/metric/<metric>', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/metric/<metric>',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/metric/<metric>')
|
||||
def metric(env, metric):
|
||||
"""Lists all information about the metric of the given name.
|
||||
@@ -798,6 +811,7 @@ def metric(env, metric):
|
||||
envs=envs,
|
||||
current_env=env)
|
||||
|
||||
|
||||
@app.route('/catalogs', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/catalogs')
|
||||
def catalogs(env):
|
||||
@@ -819,10 +833,11 @@ def catalogs(env):
|
||||
|
||||
query.add(NullOperator("catalog_timestamp", False))
|
||||
|
||||
order_by_str = '[{"field": "certname", "order": "asc"}]'
|
||||
nodes = get_or_abort(puppetdb.nodes,
|
||||
query=query,
|
||||
with_status=False,
|
||||
order_by='[{"field": "certname", "order": "asc"}]')
|
||||
order_by=oder_by_str)
|
||||
nodes, temp = tee(nodes)
|
||||
|
||||
for node in temp:
|
||||
@@ -855,7 +870,9 @@ def catalogs(env):
|
||||
log.warn('Access to catalog interface disabled by administrator')
|
||||
abort(403)
|
||||
|
||||
@app.route('/catalog/<node_name>', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
|
||||
@app.route('/catalog/<node_name>',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/catalog/<node_name>')
|
||||
def catalog_node(env, node_name):
|
||||
"""Fetches from PuppetDB the compiled catalog of a given node.
|
||||
@@ -877,7 +894,9 @@ def catalog_node(env, node_name):
|
||||
log.warn('Access to catalog interface disabled by administrator')
|
||||
abort(403)
|
||||
|
||||
@app.route('/catalog/submit', methods=['POST'], defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
|
||||
@app.route('/catalog/submit', methods=['POST'],
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/catalog/submit', methods=['POST'])
|
||||
def catalog_submit(env):
|
||||
"""Receives the submitted form data from the catalogs page and directs
|
||||
@@ -909,7 +928,9 @@ def catalog_submit(env):
|
||||
log.warn('Access to catalog interface disabled by administrator')
|
||||
abort(403)
|
||||
|
||||
@app.route('/catalogs/compare/<compare>...<against>', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
|
||||
@app.route('/catalogs/compare/<compare>...<against>',
|
||||
defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/catalogs/compare/<compare>...<against>')
|
||||
def catalog_compare(env, compare, against):
|
||||
"""Compares the catalog of one node, parameter compare, with that of
|
||||
@@ -936,6 +957,7 @@ def catalog_compare(env, compare, against):
|
||||
log.warn('Access to catalog interface disabled by administrator')
|
||||
abort(403)
|
||||
|
||||
|
||||
@app.route('/radiator', defaults={'env': app.config['DEFAULT_ENVIRONMENT']})
|
||||
@app.route('/<env>/radiator')
|
||||
def radiator(env):
|
||||
@@ -966,14 +988,12 @@ def radiator(env):
|
||||
query=metric_query)
|
||||
num_nodes = metrics[0]['count']
|
||||
|
||||
|
||||
nodes = puppetdb.nodes(
|
||||
query=query,
|
||||
unreported=app.config['UNRESPONSIVE_HOURS'],
|
||||
with_status=True
|
||||
)
|
||||
|
||||
|
||||
stats = {
|
||||
'changed_percent': 0,
|
||||
'changed': 0,
|
||||
@@ -989,8 +1009,6 @@ def radiator(env):
|
||||
'unreported': 0,
|
||||
}
|
||||
|
||||
|
||||
|
||||
for node in nodes:
|
||||
if node.status == 'unreported':
|
||||
stats['unreported'] += 1
|
||||
@@ -1005,14 +1023,14 @@ def radiator(env):
|
||||
else:
|
||||
stats['unchanged'] += 1
|
||||
|
||||
|
||||
stats['changed_percent'] = int(100 * stats['changed'] / float(num_nodes))
|
||||
stats['failed_percent'] = int(100 * stats['failed'] / float(num_nodes))
|
||||
stats['noop_percent'] = int(100 * stats['noop'] / float(num_nodes))
|
||||
stats['skipped_percent'] = int(100 * stats['skipped'] / float(num_nodes))
|
||||
stats['unchanged_percent'] = int(100 * stats['unchanged'] / float(num_nodes))
|
||||
stats['unreported_percent'] = int(100 * stats['unreported'] / float(num_nodes))
|
||||
|
||||
stats['unchanged_percent'] = int(100 * (stats['unchanged'] /
|
||||
float(num_nodes)))
|
||||
stats['unreported_percent'] = int(100 * (stats['unreported'] /
|
||||
float(num_nodes)))
|
||||
|
||||
return render_template(
|
||||
'radiator.html',
|
||||
|
||||
@@ -29,6 +29,7 @@ class QueryForm(Form):
|
||||
])
|
||||
rawjson = BooleanField('Raw JSON')
|
||||
|
||||
|
||||
class CatalogForm(Form):
|
||||
"""The form used to compare the catalogs of different nodes."""
|
||||
compare = HiddenField('compare')
|
||||
|
||||
@@ -19,9 +19,11 @@ except NameError:
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def jsonprint(value):
|
||||
return json.dumps(value, indent=2, separators=(',', ': '))
|
||||
|
||||
|
||||
def formatvalue(value):
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
@@ -35,6 +37,7 @@ def formatvalue(value):
|
||||
else:
|
||||
return str(value)
|
||||
|
||||
|
||||
def prettyprint(value):
|
||||
html = '<table class="ui basic fixed sortable table"><thead><tr>'
|
||||
|
||||
@@ -53,6 +56,7 @@ def prettyprint(value):
|
||||
html += "</tbody></table>"
|
||||
return(html)
|
||||
|
||||
|
||||
def get_or_abort(func, *args, **kwargs):
|
||||
"""Execute the function with its arguments and handle the possible
|
||||
errors that might occur.
|
||||
@@ -87,6 +91,7 @@ def yield_or_stop(generator):
|
||||
except (EmptyResponseError, ConnectionError, HTTPError):
|
||||
raise StopIteration
|
||||
|
||||
|
||||
class Pagination(object):
|
||||
|
||||
def __init__(self, page, per_page, total_count):
|
||||
@@ -111,7 +116,7 @@ class Pagination(object):
|
||||
last = 0
|
||||
for num in xrange(1, self.pages + 1):
|
||||
if num <= left_edge or \
|
||||
(num > self.page - left_current - 1 and \
|
||||
(num > self.page - left_current - 1 and
|
||||
num < self.page + right_current) or \
|
||||
num > self.pages - right_edge:
|
||||
if last + 1 != num:
|
||||
|
||||
6
requirements-test.txt
Normal file
6
requirements-test.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
pep8==1.6.2
|
||||
coverage==4.0
|
||||
mock==1.3.0
|
||||
pytest-pep8==1.0.5
|
||||
pytest-cov==2.2.1
|
||||
cov-core==1.15.0
|
||||
17
setup.cfg
17
setup.cfg
@@ -6,3 +6,20 @@ build_requires = python-setuptools
|
||||
requires = python-flask
|
||||
python-flask-wtf
|
||||
python-pypuppetdb
|
||||
[pep8]
|
||||
max-line-length=100
|
||||
exclude=venv,dist,build
|
||||
ignore=E402
|
||||
|
||||
[nosetests]
|
||||
with-coverage = 1
|
||||
with-xunit = 1
|
||||
cover-package = puppetboard
|
||||
|
||||
[flake8]
|
||||
exclude=venv
|
||||
|
||||
[pytest]
|
||||
addopts = --cov=puppetboard --cov-report=term-missing
|
||||
norecursedirs = docs .tox venv
|
||||
pep8ignore = E402
|
||||
|
||||
19
test/test_app.py
Normal file
19
test/test_app.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import os
|
||||
from puppetboard import app
|
||||
import unittest
|
||||
import tempfile
|
||||
|
||||
|
||||
class AppTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_first_test(self):
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user