def test_db_invalid_version(mocker, mock_err_log): mocker.patch.object(app.puppetdb, 'current_version', return_value='4') err = u"Unable to determine version from string: '%s'" % (4) result = utils.get_db_version(app.puppetdb) mock_err_log.assert_called_with(err) assert (4, 0, 0) < result assert (4, 2, 0) == result
def index(env): """This view generates the index page and displays a set of metrics and latest reports on nodes fetched from PuppetDB. :param env: Search for nodes in this (Catalog and Fact) environment :type env: :obj:`string` """ envs = environments() check_env(env, envs) stats = status_count(env) if stats['total'] < 1000: stats['num_resources'] = get_count( 'resources', EqualsOperator("environment", env)) # average resource / node try: stats['avg_resources_node'] = "{0:10.0f}".format( (stats['num_resources'] / stats['total'])) except ZeroDivisionError: stats['avg_resources_node'] = 0 else: prefix = 'puppetlabs.puppetdb.population' query_type = '' # Puppet DB version changed the query format from 3.2.0 # to 4.0 when querying mbeans if get_db_version(puppetdb) < (4, 0, 0): query_type = 'type=default,' stats['num_resources'] = get_or_abort( puppetdb.metric, "{0}{1}".format( prefix, ':%sname=num-resources' % query_type))['Value'] stats['avg_resources_node'] = int(get_or_abort( puppetdb.metric, "{0}{1}".format( prefix, ':%sname=avg-resources-per-node' % query_type))['Value']) paging_args = {'limit': app.config['NORMAL_TABLE_COUNT'], 'offset': 0} order_arg = '[{"field": "catalog_timestamp", "order": "desc"}]' nodes = get_or_abort(puppetdb.nodes, query=get_node_env_query(env), unreported=app.config['UNRESPONSIVE_HOURS'], with_status=True, order_by=order_arg, **paging_args) return render_template( 'index.html', nodes=nodes, stats=stats, envs=envs, current_env=env )
def test_db_empty_response(mocker, mock_err_log): err = "Empty Response" def connection_error(): raise EmptyResponseError(err) mocker.patch.object(app.puppetdb, 'current_version', side_effect=connection_error) result = utils.get_db_version(app.puppetdb) mock_err_log.assert_called_with(err) assert result == ()
def test_db_version_good(mocker, mock_info_log): mocker.patch.object(app.puppetdb, 'current_version', return_value='4.2.0') err = 'PuppetDB Version %d.%d.%d' % (4, 2, 0) result = utils.get_db_version(app.puppetdb) mock_info_log.assert_called_with(err) assert (4, 0, 0) < result assert (4, 2, 0) == result assert (3, 2, 0) < result assert (4, 3, 0) > result assert (5, 0, 0) > result assert (4, 2, 1) > result
def test_db_connection_error(mocker, mock_err_log): err = "ConnectionError" def connection_error(): x = Response() x.status_code = 500 x.reason = err raise ConnectionError(err, response=x) mocker.patch.object(app.puppetdb, 'current_version', side_effect=connection_error) result = utils.get_db_version(app.puppetdb) mock_err_log.assert_called_with(err) assert result == ()
def test_db_http_error(mocker, mock_err_log): err = "NotFound" def raise_http_error(): x = Response() x.status_code = 404 x.reason = err raise HTTPError(err, response=x) mocker.patch.object(app.puppetdb, 'current_version', side_effect=raise_http_error) result = utils.get_db_version(app.puppetdb) mock_err_log.assert_called_with(err) assert result == ()
def radiator(env): """This view generates a simplified monitoring page akin to the radiator view in puppet dashboard """ envs = environments() check_env(env, envs) if env == '*': query_type = '' if get_db_version(puppetdb) < (4, 0, 0): query_type = 'type=default,' query = None metrics = get_or_abort( puppetdb.metric, 'puppetlabs.puppetdb.population:%sname=num-nodes' % query_type) num_nodes = metrics['Value'] else: query = AndOperator() metric_query = ExtractOperator() query.add(EqualsOperator("catalog_environment", env)) query.add(EqualsOperator("facts_environment", env)) metric_query.add_field(FunctionOperator('count')) metric_query.add_query(query) metrics = get_or_abort(puppetdb._query, 'nodes', 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, 'failed_percent': 0, 'failed': 0, 'noop_percent': 0, 'noop': 0, 'skipped_percent': 0, 'skipped': 0, 'unchanged_percent': 0, 'unchanged': 0, 'unreported_percent': 0, 'unreported': 0, } for node in nodes: if node.status == 'unreported': stats['unreported'] += 1 elif node.status == 'changed': stats['changed'] += 1 elif node.status == 'failed': stats['failed'] += 1 elif node.status == 'noop': stats['noop'] += 1 elif node.status == 'skipped': stats['skipped'] += 1 else: stats['unchanged'] += 1 try: 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))) except ZeroDivisionError: stats['changed_percent'] = 0 stats['failed_percent'] = 0 stats['noop_percent'] = 0 stats['skipped_percent'] = 0 stats['unchanged_percent'] = 0 stats['unreported_percent'] = 0 if ('Accept' in request.headers and request.headers["Accept"] == 'application/json'): return jsonify(**stats) return render_template('radiator.html', stats=stats, total=num_nodes)
def index(env): """This view generates the index page and displays a set of metrics and latest reports on nodes fetched from PuppetDB. :param env: Search for nodes in this (Catalog and Fact) environment :type env: :obj:`string` """ envs = environments() metrics = {'num_nodes': 0, 'num_resources': 0, 'avg_resources_node': 0} check_env(env, envs) if env == '*': query = app.config['OVERVIEW_FILTER'] prefix = 'puppetlabs.puppetdb.population' query_type = '' # Puppet DB version changed the query format from 3.2.0 # to 4.0 when querying mbeans if get_db_version(puppetdb) < (4, 0, 0): query_type = 'type=default,' num_nodes = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=num-nodes' % query_type)) num_resources = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=num-resources' % query_type)) avg_resources_node = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=avg-resources-per-node' % query_type)) metrics['num_nodes'] = num_nodes['Value'] metrics['num_resources'] = num_resources['Value'] metrics['avg_resources_node'] = "{0:10.0f}".format( avg_resources_node['Value']) else: query = AndOperator() query.add(EqualsOperator('catalog_environment', env)) query.add(EqualsOperator('facts_environment', env)) num_nodes_query = ExtractOperator() num_nodes_query.add_field(FunctionOperator('count')) num_nodes_query.add_query(query) if app.config['OVERVIEW_FILTER'] is not None: query.add(app.config['OVERVIEW_FILTER']) num_resources_query = ExtractOperator() num_resources_query.add_field(FunctionOperator('count')) num_resources_query.add_query(EqualsOperator("environment", env)) num_nodes = get_or_abort(puppetdb._query, 'nodes', query=num_nodes_query) num_resources = get_or_abort(puppetdb._query, 'resources', query=num_resources_query) metrics['num_nodes'] = num_nodes[0]['count'] metrics['num_resources'] = num_resources[0]['count'] try: metrics['avg_resources_node'] = "{0:10.0f}".format( (num_resources[0]['count'] / num_nodes[0]['count'])) except ZeroDivisionError: metrics['avg_resources_node'] = 0 nodes = get_or_abort(puppetdb.nodes, query=query, unreported=app.config['UNRESPONSIVE_HOURS'], with_status=True) nodes_overview = [] stats = { 'changed': 0, 'unchanged': 0, 'failed': 0, 'unreported': 0, 'noop': 0 } for node in nodes: if node.status == 'unreported': stats['unreported'] += 1 elif node.status == 'changed': stats['changed'] += 1 elif node.status == 'failed': stats['failed'] += 1 elif node.status == 'noop': stats['noop'] += 1 else: stats['unchanged'] += 1 if node.status != 'unchanged': nodes_overview.append(node) return render_template('index.html', metrics=metrics, nodes=nodes_overview, stats=stats, envs=envs, current_env=env)
def index(env): """This view generates the index page and displays a set of metrics and latest reports on nodes fetched from PuppetDB. :param env: Search for nodes in this (Catalog and Fact) environment :type env: :obj:`string` """ envs = environments() metrics = {'num_nodes': 0, 'num_resources': 0, 'avg_resources_node': 0} check_env(env, envs) if env == '*': query = app.config['OVERVIEW_FILTER'] prefix = 'puppetlabs.puppetdb.population' db_version = get_db_version(puppetdb) query_type, metric_version = metric_params(db_version) num_nodes = get_or_abort(puppetdb.metric, "{0}{1}".format( prefix, ':%sname=num-nodes' % query_type), version=metric_version) num_resources = get_or_abort(puppetdb.metric, "{0}{1}".format( prefix, ':%sname=num-resources' % query_type), version=metric_version) avg_resources_node = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=avg-resources-per-node' % query_type), version=metric_version) metrics['num_nodes'] = num_nodes['Value'] metrics['num_resources'] = num_resources['Value'] try: # Compute our own average because avg_resources_node['Value'] # returns a string of the format "num_resources/num_nodes" # example: "1234/9" instead of doing the division itself. metrics['avg_resources_node'] = "{0:10.0f}".format( (num_resources['Value'] / num_nodes['Value'])) except ZeroDivisionError: metrics['avg_resources_node'] = 0 else: query = AndOperator() query.add(EqualsOperator('catalog_environment', env)) num_nodes_query = ExtractOperator() num_nodes_query.add_field(FunctionOperator('count')) num_nodes_query.add_query(query) if app.config['OVERVIEW_FILTER'] is not None: query.add(app.config['OVERVIEW_FILTER']) num_resources_query = ExtractOperator() num_resources_query.add_field(FunctionOperator('count')) num_resources_query.add_query(EqualsOperator("environment", env)) num_nodes = get_or_abort(puppetdb._query, 'nodes', query=num_nodes_query) num_resources = get_or_abort(puppetdb._query, 'resources', query=num_resources_query) metrics['num_nodes'] = num_nodes[0]['count'] metrics['num_resources'] = num_resources[0]['count'] try: metrics['avg_resources_node'] = "{0:10.0f}".format( (num_resources[0]['count'] / num_nodes[0]['count'])) except ZeroDivisionError: metrics['avg_resources_node'] = 0 nodes = get_or_abort(puppetdb.nodes, query=query, unreported=app.config['UNRESPONSIVE_HOURS'], with_status=True, with_event_numbers=app.config['WITH_EVENT_NUMBERS']) nodes_overview = [] stats = { 'changed': 0, 'unchanged': 0, 'failed': 0, 'unreported': 0, 'noop': 0 } for node in nodes: if node.status == 'unreported': stats['unreported'] += 1 elif node.status == 'changed': stats['changed'] += 1 elif node.status == 'failed': stats['failed'] += 1 elif node.status == 'noop': stats['noop'] += 1 else: stats['unchanged'] += 1 if node.status != 'unchanged': nodes_overview.append(node) return render_template('index.html', metrics=metrics, nodes=nodes_overview, stats=stats, envs=envs, current_env=env)
def radiator(env): """This view generates a simplified monitoring page akin to the radiator view in puppet dashboard """ envs = environments() check_env(env, envs) if env == '*': query_type = '' if get_db_version(puppetdb) < (4, 0, 0): query_type = 'type=default,' query = None metrics = get_or_abort( puppetdb.metric, 'puppetlabs.puppetdb.population:%sname=num-nodes' % query_type) num_nodes = metrics['Value'] else: query = AndOperator() metric_query = ExtractOperator() query.add(EqualsOperator("catalog_environment", env)) query.add(EqualsOperator("facts_environment", env)) metric_query.add_field(FunctionOperator('count')) metric_query.add_query(query) metrics = get_or_abort( puppetdb._query, 'nodes', 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, 'failed_percent': 0, 'failed': 0, 'noop_percent': 0, 'noop': 0, 'skipped_percent': 0, 'skipped': 0, 'unchanged_percent': 0, 'unchanged': 0, 'unreported_percent': 0, 'unreported': 0, } for node in nodes: if node.status == 'unreported': stats['unreported'] += 1 elif node.status == 'changed': stats['changed'] += 1 elif node.status == 'failed': stats['failed'] += 1 elif node.status == 'noop': stats['noop'] += 1 elif node.status == 'skipped': stats['skipped'] += 1 else: stats['unchanged'] += 1 try: 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))) except ZeroDivisionError: stats['changed_percent'] = 0 stats['failed_percent'] = 0 stats['noop_percent'] = 0 stats['skipped_percent'] = 0 stats['unchanged_percent'] = 0 stats['unreported_percent'] = 0 if ('Accept' in request.headers and request.headers["Accept"] == 'application/json'): return jsonify(**stats) return render_template( 'radiator.html', stats=stats, total=num_nodes )
def index(env): """This view generates the index page and displays a set of metrics and latest reports on nodes fetched from PuppetDB. :param env: Search for nodes in this (Catalog and Fact) environment :type env: :obj:`string` """ envs = environments() metrics = { 'num_nodes': 0, 'num_resources': 0, 'avg_resources_node': 0} check_env(env, envs) if env == '*': query = app.config['OVERVIEW_FILTER'] prefix = 'puppetlabs.puppetdb.population' query_type = '' # Puppet DB version changed the query format from 3.2.0 # to 4.0 when querying mbeans if get_db_version(puppetdb) < (4, 0, 0): query_type = 'type=default,' num_nodes = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=num-nodes' % query_type)) num_resources = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=num-resources' % query_type)) avg_resources_node = get_or_abort( puppetdb.metric, "{0}{1}".format(prefix, ':%sname=avg-resources-per-node' % query_type)) metrics['num_nodes'] = num_nodes['Value'] metrics['num_resources'] = num_resources['Value'] metrics['avg_resources_node'] = "{0:10.0f}".format( avg_resources_node['Value']) else: query = AndOperator() query.add(EqualsOperator('catalog_environment', env)) query.add(EqualsOperator('facts_environment', env)) num_nodes_query = ExtractOperator() num_nodes_query.add_field(FunctionOperator('count')) num_nodes_query.add_query(query) if app.config['OVERVIEW_FILTER'] is not None: query.add(app.config['OVERVIEW_FILTER']) num_resources_query = ExtractOperator() num_resources_query.add_field(FunctionOperator('count')) num_resources_query.add_query(EqualsOperator("environment", env)) num_nodes = get_or_abort( puppetdb._query, 'nodes', query=num_nodes_query) num_resources = get_or_abort( puppetdb._query, 'resources', query=num_resources_query) metrics['num_nodes'] = num_nodes[0]['count'] metrics['num_resources'] = num_resources[0]['count'] try: metrics['avg_resources_node'] = "{0:10.0f}".format( (num_resources[0]['count'] / num_nodes[0]['count'])) except ZeroDivisionError: metrics['avg_resources_node'] = 0 nodes = get_or_abort(puppetdb.nodes, query=query, unreported=app.config['UNRESPONSIVE_HOURS'], with_status=True) nodes_overview = [] stats = { 'changed': 0, 'unchanged': 0, 'failed': 0, 'unreported': 0, 'noop': 0 } for node in nodes: if node.status == 'unreported': stats['unreported'] += 1 elif node.status == 'changed': stats['changed'] += 1 elif node.status == 'failed': stats['failed'] += 1 elif node.status == 'noop': stats['noop'] += 1 else: stats['unchanged'] += 1 if node.status != 'unchanged': nodes_overview.append(node) return render_template( 'index.html', metrics=metrics, nodes=nodes_overview, stats=stats, envs=envs, current_env=env )