Facts page fix + performance revamp
Removed facts query to let only fact-names. facts query time grow pretty quickly with number of nodes. Drawback: no filter on environment (which seems acceptable) Add testing about view and column repartition (broken in jinja2 2.9.X / inner loop variables). Rework facts page (jinja 2.9 compliant)
This commit is contained in:
@@ -630,33 +630,33 @@ def facts(env):
|
|||||||
check_env(env, envs)
|
check_env(env, envs)
|
||||||
facts = []
|
facts = []
|
||||||
order_by = '[{"field": "name", "order": "asc"}]'
|
order_by = '[{"field": "name", "order": "asc"}]'
|
||||||
|
|
||||||
if env == '*':
|
|
||||||
facts = get_or_abort(puppetdb.fact_names)
|
facts = get_or_abort(puppetdb.fact_names)
|
||||||
else:
|
|
||||||
query = ExtractOperator()
|
|
||||||
query.add_field(str('name'))
|
|
||||||
query.add_query(EqualsOperator("environment", env))
|
|
||||||
query.add_group_by(str("name"))
|
|
||||||
|
|
||||||
for names in get_or_abort(puppetdb._query,
|
facts_columns = [[]]
|
||||||
'facts',
|
letter = None
|
||||||
query=query,
|
letter_list = None
|
||||||
order_by=order_by):
|
break_size = (len(facts) / 4) + 1
|
||||||
facts.append(names['name'])
|
next_break = break_size
|
||||||
|
count = 0
|
||||||
facts_dict = collections.defaultdict(list)
|
|
||||||
for fact in facts:
|
for fact in facts:
|
||||||
letter = fact[0].upper()
|
count += 1
|
||||||
letter_list = facts_dict[letter]
|
|
||||||
letter_list.append(fact)
|
if letter != fact[0].upper() or not letter:
|
||||||
facts_dict[letter] = letter_list
|
if count > next_break:
|
||||||
|
# Create a new column
|
||||||
|
facts_columns.append([])
|
||||||
|
next_break += break_size
|
||||||
|
if letter_list:
|
||||||
|
facts_columns[-1].append(letter_list)
|
||||||
|
# Reset
|
||||||
|
letter = fact[0].upper()
|
||||||
|
letter_list = []
|
||||||
|
|
||||||
|
letter_list.append(fact)
|
||||||
|
facts_columns[-1].append(letter_list)
|
||||||
|
|
||||||
sorted_facts_dict = sorted(facts_dict.items())
|
|
||||||
return render_template('facts.html',
|
return render_template('facts.html',
|
||||||
facts_dict=sorted_facts_dict,
|
facts_columns=facts_columns,
|
||||||
facts_len=(sum(map(len, facts_dict.values())) +
|
|
||||||
len(facts_dict) * 5),
|
|
||||||
envs=envs,
|
envs=envs,
|
||||||
current_env=env)
|
current_env=env)
|
||||||
|
|
||||||
|
|||||||
@@ -4,26 +4,19 @@
|
|||||||
<input autofocus="autofocus" class="filter-list" placeholder="Type here to filter...">
|
<input autofocus="autofocus" class="filter-list" placeholder="Type here to filter...">
|
||||||
</div>
|
</div>
|
||||||
<div class="ui searchable stackable doubling four column grid factlist">
|
<div class="ui searchable stackable doubling four column grid factlist">
|
||||||
|
{%- for column in facts_columns %}
|
||||||
<div class="column">
|
<div class="column">
|
||||||
{%- set facts_count = 0 -%}
|
{%- for letter in column %}
|
||||||
{%- set break = facts_len//4 + 1 -%}
|
|
||||||
{%- for key,facts_list in facts_dict %}
|
|
||||||
<div class="ui list_hide_segment segment">
|
<div class="ui list_hide_segment segment">
|
||||||
<a class="ui darkblue ribbon label">{{key}}</a>
|
<a class="ui darkblue ribbon label">{{ letter[0][0]|upper }}</a>
|
||||||
<ul>
|
<ul>
|
||||||
{%- for fact in facts_list %}
|
{%- for fact in letter %}
|
||||||
<li><a href="{{url_for('fact', env=current_env, fact=fact)}}">{{ fact }}</a></li>
|
<li><a href="{{url_for('fact', env=current_env, fact=fact)}}">{{ fact }}</a></li>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{%- set facts_count = facts_count + facts_list|length -%}
|
{%- endfor %}
|
||||||
{%- if facts_count >= break -%}
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
{%- set break = facts_len//4 + 1 + break -%}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- set facts_count = facts_count + 5 -%}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -620,3 +620,22 @@ def test_catalogs_json_compare(client, mocker,
|
|||||||
"action": "/catalogs/compare/node-unreported...node-%s" %
|
"action": "/catalogs/compare/node-unreported...node-%s" %
|
||||||
found_status})
|
found_status})
|
||||||
assert len(val) == 1
|
assert len(val) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_facts_view(client, mocker, mock_puppetdb_environments):
|
||||||
|
query_data = {
|
||||||
|
'fact-names': [[chr(i) for i in range(ord('a'), ord('z') + 1)]]
|
||||||
|
}
|
||||||
|
|
||||||
|
dbquery = MockDbQuery(query_data)
|
||||||
|
|
||||||
|
mocker.patch.object(app.puppetdb, '_query', side_effect=dbquery.get)
|
||||||
|
|
||||||
|
rv = client.get('/facts')
|
||||||
|
assert rv.status_code == 200
|
||||||
|
soup = BeautifulSoup(rv.data, 'html.parser')
|
||||||
|
assert soup.title.contents[0] == 'Puppetboard'
|
||||||
|
|
||||||
|
searchable = soup.find('div', {'class': 'searchable'})
|
||||||
|
vals = searchable.find_all('div', {'class': 'column'})
|
||||||
|
assert len(vals) == 4
|
||||||
|
|||||||
Reference in New Issue
Block a user