* fix: Regressin in poller_time table handling
* fix: Host Template ordering was broken
* fix: Remove Unit test as the logic was incorrect
* fix: PSR on quotes
* fix(csv): align export and graph sample windows
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci(csv): satisfy release policy checks
* test(csv): align legacy capacity contract
* test(csv): add standard license headers
* fix(rrd): infer step from trailing fetch row
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci(csv): trigger on resolution query coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): mirror fetch helper arguments
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): isolate percentile globals
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): annotate intentional eval
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): restore integration config
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): enable strict types
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): restore font config
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: align CSV coverage with supported PHP versions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* fix: commit transactions on MySQL as well as MariaDB
db_commit_transaction() gated the commit on SELECT @@in_transaction. That
variable is MariaDB only; MySQL answers 'Unknown system variable
in_transaction', so the guard was false on every MySQL install and the commit
never ran. The transaction was left open and the function reported failure.
Verified against both engines: MariaDB returns 0, MySQL 8 raises ERROR 1193.
Every caller was affected, including device removal, which reports 'Unable to
remove Device N because its database transaction could not be committed' and
leaves the device in place.
Use PDO::inTransaction(), which tracks the state itself and answers the same
question on both engines.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Update transaction regression assertion
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7024: do not delete still-running poller_time rows on cycle start
The overrun path deleted every poller_time row for the poller, including the
in-flight ones it had just counted, so overrunning processes lost their
tracking. Restrict the delete to completed rows.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7028: restore identifier and connection safety in the db layer
_db_replace interpolated caller-supplied column keys as backtick identifiers
without escaping, and db_commit_transaction checked @@in_transaction on the
default connection rather than the one passed in. Both were correct on 1.2.x
and regressed on develop.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7341: size the CSV export maxrows to the requested span
The export hardcoded --maxrows=10000, truncating wide date ranges regardless
of the data source profile step.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7421: offset automation_get_next_host through the 32-bit integer
The hand-rolled octet walk subtracted the wrong magnitude per octet and
emitted out-of-range octets for ranges wider than a /16.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7030: skip the poller_output ENGINE=MEMORY conversion when already applied
The output-table refresh ran ALTER TABLE poller_output ENGINE=MEMORY every
cycle even though the swapped-in copy already inherits the engine, adding a
metadata-locking DDL to the hot path. Probe the current engine and convert
only when needed.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7342: prefer snmpEngineTime only when it covers system uptime
update_system_mibs preferred snmpEngineTime (x100) over sysUpTime whenever it
was present, so an SNMP engine that restarts independently of the system (for
example OpenBSD snmpd) made the stored uptime drop, which reads as a reboot
and forces a perpetual reindex with mass 'U' results. Capture both values and
use snmpEngineTime only when it is at least the system uptime, which still
covers the 32-bit sysUpTime wrap.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7403: scale lmsensors readings in the get path like the query path
The get path returned the raw milli-unit SNMP counter while the query path
divided voltage and temperature by 1000 (and corrected negative voltages), so
a get gave values 1000x too large. Apply the same scaling before returning.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7029: propagate the reconnected handle back to the caller
db_check_reconnect() closed the dead connection, opened a new one, and
returned true without giving the new handle back, so the db_execute_prepared
retry ran its query against the connection that was just closed. Take $db_conn
by reference and assign the fresh handle; the one caller that passed a literal
false now passes a variable.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: refresh sink inventory baseline
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: refresh architectural hotspots baseline
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7474: return valid after correcting the theme to selected_theme
is_valid_theme() corrected an invalid theme to selected_theme but left $valid
false, so callers saw the theme as invalid even though it had been fixed.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7462: allow SELECT aliases as sortable automation columns
site_name and host_template_name are aliases (s.name AS site_name), valid in
ORDER BY but not real columns, so api_automation_column_exists() rejected them
and the site-name sort silently failed.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7456: bind the OS value in the automation OS filter
The OS filter built 'os = ?' but bound the network value, so filtering by OS
matched on the wrong input.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7491: filter host_template_id against its own column
html_make_device_where() compared h.location to the host_template_id value
instead of h.host_template_id.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7479: apply the hostname and description filters in get_hosts
The REST get_hosts() honored host_id/poller/site/template/location but ignored
the hostname and description filters its callers pass; add them as bound LIKE.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#7475: authorize a direct client-IP poller match before the hostname guard
A poller configured by IP with no hostname-based pollers was rejected because
the empty-hostname guard ran before the direct-match check, even though the
client address exactly matched a poller's configured address.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Guard two divisors that PHP 8 makes fatal
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: consolidate functional fix changelog
* test: cover consolidated functional fixes
* docs: identify consolidated functional fixes
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>