Skip to content

Commit

Permalink
Add MVP reports (#7)
Browse files Browse the repository at this point in the history
* Add MVP reports

* Remove unused report
  • Loading branch information
ShimShtein authored Jan 16, 2025
1 parent 0099555 commit 6f6ef3b
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 16 deletions.
92 changes: 92 additions & 0 deletions definitions/reports/inventory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# copy the file and add the .rb suffix
module Checks
module Report
class Inventory < ForemanMaintain::Report
metadata do
description 'Facts about hosts and the rest of the inventory'
end

# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def run
# Hosts
hosts_by_type_count =
feature(:foreman_database).
query("select type, count(*) from hosts group by type").
to_h { |row| [(row['type'] || '').sub('Host::', ''), row['count'].to_i] }

# OS usage
hosts_by_os_count =
feature(:foreman_database).
query(
<<-SQL
select max(operatingsystems.name) as os_name, count(*) as hosts_count
from hosts inner join operatingsystems on operatingsystem_id = operatingsystems.id
group by operatingsystem_id
SQL
).
to_h { |row| [row['os_name'], row['hosts_count'].to_i] }

# Facts usage
facts_by_type =
feature(:foreman_database).
query(
<<-SQL
select fact_names.type,
min(fact_values.updated_at) as min_update_time,
max(fact_values.updated_at) as max_update_time,
count(fact_values.id) as values_count
from fact_values inner join fact_names on fact_name_id = fact_names.id
group by fact_names.type
SQL
).
to_h { |row| [row['type'].sub('FactName', ''), to_fact_hash(row)] }

# Audits
audits_query =
feature(:foreman_database).
query(
<<-SQL
select count(*) as records_count,
min(created_at) as min_created_at,
max(created_at) as max_created_at
from audits
SQL
)
audits = to_audits_record(audits_query.first)

# Parameters
parameters =
feature(:foreman_database).
query("select type, count(*) from parameters group by type").
to_h { |row| [row['type'], row['count'].to_i] }

data = {}

data.merge!(flatten(hosts_by_type_count, 'hosts_by_type_count'))
data.merge!(flatten(hosts_by_os_count, 'hosts_by_os_count'))
data.merge!(flatten(facts_by_type, 'facts_by_type'))
data.merge!(flatten(audits, 'audits'))
data.merge!(flatten(parameters, 'parameters_count'))

self.data = data
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength

def to_fact_hash(row)
{
min_update_time: row['min_update_time'],
max_update_time: row['max_update_time'],
values_count: row['values_count'].to_i,
}
end

def to_audits_record(row)
{
records_count: row['records_count'].to_i,
min_created_at: row['min_created_at'],
max_created_at: row['max_created_at'],
}
end
end
end
end
108 changes: 108 additions & 0 deletions definitions/reports/platform.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# copy the file and add the .rb suffix
module Checks
module Report
class Platform < ForemanMaintain::Report
metadata do
description 'Report about platform usages'
end

# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def run
# General
smart_proxies_count = sql_count('smart_proxies')
smart_proxies_creation_date =
feature(:foreman_database).
query("select id, created_at from smart_proxies").
to_h { |row| [row['id'], row['created_at']] }

# RBAC
total_users_count = sql_count('users')
non_admin_users_count = sql_count('users where admin = false')

custom_roles_count = sql_count('roles where origin = null')
taxonomies_counts =
feature(:foreman_database).
query("select type, count(*) from taxonomies group by type").
to_h { |row| [row['type'], row['count'].to_i] }

# Settings
modified_settings =
feature(:foreman_database).
query("select name from settings").
map { |setting_line| setting_line['name'] }.
join(',')

# User groups
user_groups_count = sql_count('usergroups')

# Bookmarks
bookmarks_by_public_by_type =
feature(:foreman_database).
query(
<<-SQL
select public, owner_type, count(*)
from bookmarks
group by public, owner_type
SQL
).
to_h do |row|
[
"#{row['public'] ? 'public' : 'private'}#{flatten_separator}#{row['owner_type']}",
row['count'].to_i,
]
end
# bookmarks_by_owner =
# feature(:foreman_database).
# query(
# <<-SQL
# select owner_type, owner_id, count(*)
# from bookmarks
# group by owner_type, owner_id
# SQL
# ).
# to_h do |row|
# [
# "#{row['owner_type']}#{flatten_separator}#{row['owner_id']}",
# row['count'].to_i,
# ]
# end

# Mail notifications
# users_per_mail_notification =
# feature(:foreman_database).
# query(
# <<-SQL
# select
# max(mail_notifications.name) as notification_name,
# count(user_mail_notifications.user_id)
# from user_mail_notifications inner join mail_notifications
# on mail_notification_id = mail_notifications.id
# group by mail_notification_id
# SQL
# ).
# to_h { |row| [row['notification_name'], row['count'].to_i] }

user_mail_notifications_count = sql_count('user_mail_notifications')

data = {
smart_proxies_count: smart_proxies_count,
total_users_count: total_users_count,
non_admin_users_count: non_admin_users_count,
custom_roles_count: custom_roles_count,
modified_settings: modified_settings,
user_groups_count: user_groups_count,
user_mail_notifications_count: user_mail_notifications_count,
}

data.merge!(flatten(smart_proxies_creation_date, 'smart_proxies_creation_date'))
data.merge!(flatten(taxonomies_counts, 'taxonomies_counts'))
data.merge!(flatten(bookmarks_by_public_by_type, 'bookmarks_by_public_by_type'))
# data.merge!(flatten(bookmarks_by_owner, 'bookmarks_by_owner'))
# data.merge!(flatten(users_per_mail_notification, 'users_per_mail_notification'))

self.data = data
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
end
end
end
101 changes: 101 additions & 0 deletions definitions/reports/provisioning.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
module Checks
module Report
class Provisioning < ForemanMaintain::Report
metadata do
description 'Provisioning facts about the system'
end

# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
def run
hosts_in_3_months =
sql_count(
<<-SQL
hosts WHERE managed = true AND created_at >= current_date - interval '3 months'
SQL
)

# Compute resources
compute_resources_by_type =
feature(:foreman_database).
query(
<<-SQL
select type, count(*)
from compute_resources
group by type
SQL
).
to_h { |row| [row['type'], row['count'].to_i] }

hosts_by_compute_resources_type =
feature(:foreman_database).
query(
<<-SQL
select compute_resources.type, count(hosts.id)
from hosts left outer join compute_resources on compute_resource_id = compute_resources.id
group by compute_resources.type
SQL
).
to_h { |row| [row['type'] || 'baremetal', row['count'].to_i] }
hosts_by_compute_profile =
feature(:foreman_database).
query(
<<-SQL
select max(compute_profiles.name) as name, count(hosts.id)
from hosts left outer join compute_profiles on compute_profile_id = compute_profiles.id
group by compute_profile_id
SQL
).
to_h { |row| [row['name'] || 'none', row['count'].to_i] }

# Bare metal
nics_by_type_count =
feature(:foreman_database).
query(
<<-SQL
select type, count(*)
from nics
group by type
SQL
).
to_h { |row| [(row['type'] || 'none').sub('Nic::', ''), row['count'].to_i] }
discovery_rules_count = sql_count('discovery_rules')
hosts_by_managed_count =
feature(:foreman_database).
query(
<<-SQL
select managed, count(*)
from hosts
group by managed
SQL
).
to_h { |row| [row['managed'] == 't' ? 'managed' : 'unmanaged', row['count'].to_i] }

# Templates
non_default_templates_per_type =
feature(:foreman_database).
query(
<<-SQL
select type, count(*) from templates
where templates.default = false
group by type
SQL
).
to_h { |row| [row['type'], row['count'].to_i] }

data = {
discovery_rules_count: discovery_rules_count,
managed_hosts_created_in_last_3_months: hosts_in_3_months,
}
data.merge!(flatten(compute_resources_by_type, 'compute_resources_by_type'))
data.merge!(flatten(hosts_by_compute_resources_type, 'hosts_by_compute_resources_type'))
data.merge!(flatten(hosts_by_compute_profile, 'hosts_by_compute_profile'))
data.merge!(flatten(nics_by_type_count, 'nics_by_type'))
data.merge!(flatten(hosts_by_managed_count, 'managed_hosts_count'))
data.merge!(flatten(non_default_templates_per_type, 'non_default_templates_per_type'))

self.data = data
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
end
end
end
16 changes: 0 additions & 16 deletions definitions/reports/provisioning_usage.rb

This file was deleted.

17 changes: 17 additions & 0 deletions lib/foreman_maintain/report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def sql_count(sql, column: '*', cte: '')
def sql_as_count(selection, sql, cte: '')
query = "#{cte} SELECT #{selection} AS COUNT FROM #{sql}"
feature(:foreman_database).query(query).first['count'].to_i
rescue StandardError
nil
end

def sql_setting(name)
Expand All @@ -22,6 +24,17 @@ def sql_setting(name)
(result || {})['value']
end

def flatten(hash, prefix = '')
hash.each_with_object({}) do |(key, value), result|
new_key = "#{prefix}#{prefix.empty? ? '' : flatten_separator}#{key}"
if value.is_a? Hash
result.merge!(flatten(value, new_key))
else
result[new_key] = value
end
end
end

def table_exists(table)
sql_count("information_schema.tables WHERE table_name = '#{table}'").positive?
end
Expand All @@ -38,5 +51,9 @@ def __run__(execution)
rescue StandardError => e
set_warn(e.message)
end

def flatten_separator
'|'
end
end
end

0 comments on commit 6f6ef3b

Please sign in to comment.