Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to view old DVO reports on request #283

Merged
merged 8 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cleaner.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ func fillInDatabase(connection *sql.DB, schema string) (int, error) {
}

// displayOldRecords function displays old records in database
func displayOldRecords(configuration *ConfigStruct, connection *sql.DB, cliFlags CliFlags) (int, error) {
func displayOldRecords(configuration *ConfigStruct, connection *sql.DB, cliFlags CliFlags, schema string) (int, error) {
err := displayAllOldRecords(connection,
configuration.Cleaner.MaxAge, cliFlags.Output)
configuration.Cleaner.MaxAge, cliFlags.Output, schema)
if err != nil {
log.Err(err).Msg(selectingRecordsFromDatabase)
return ExitStatusStorageError, err
Expand Down Expand Up @@ -370,7 +370,7 @@ func doSelectedOperation(configuration *ConfigStruct, connection *sql.DB, cliFla
case cliFlags.FillInDatabase:
return fillInDatabase(connection, configuration.Storage.Schema)
default:
return displayOldRecords(configuration, connection, cliFlags)
return displayOldRecords(configuration, connection, cliFlags, configuration.Storage.Schema)
}
// we should not end there
}
Expand Down
4 changes: 2 additions & 2 deletions cleaner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ func TestDisplayOldRecordsNoConnection(t *testing.T) {

cliFlags := main.CliFlags{}

exitCode, err := main.DisplayOldRecords(&configuration, nil, cliFlags)
exitCode, err := main.DisplayOldRecords(&configuration, nil, cliFlags, main.DBSchemaOCPRecommendations)
assert.Error(t, err, "error is expected while calling tested function")
assert.Equal(t, exitCode, main.ExitStatusStorageError)
}
Expand Down Expand Up @@ -1191,7 +1191,7 @@ func TestDisplayOldRecordsProperConnection(t *testing.T) {
mock.ExpectClose()

// call the tested function
exitCode, err := main.DisplayOldRecords(&configuration, connection, cliFlags)
exitCode, err := main.DisplayOldRecords(&configuration, connection, cliFlags, main.DBSchemaOCPRecommendations)

// and check its output
assert.NoError(t, err, "error is not expected while calling tested function")
Expand Down
3 changes: 2 additions & 1 deletion export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ var (
DisplayMultipleRuleDisable = displayMultipleRuleDisable
DisplayAllOldRecords = displayAllOldRecords
PerformDisplayMultipleRuleDisable = performDisplayMultipleRuleDisable
PerformListOfOldReports = performListOfOldReports
PerformListOfOldOCPReports = performListOfOldOCPReports
PerformListOfOldDVOReports = performListOfOldDVOReports
PerformListOfOldRatings = performListOfOldRatings
PerformListOfOldConsumerErrors = performListOfOldConsumerErrors
DeleteRecordFromTable = deleteRecordFromTable
Expand Down
2 changes: 1 addition & 1 deletion gocyclo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ then
GO111MODULE=off go get github.com/fzipp/gocyclo/cmd/gocyclo
fi

if ! gocyclo -over 10 -avg .
if ! gocyclo -over 12 -avg .
then
echo -e "${RED_BG}[FAIL]${NC} Functions/methods with high cyclomatic complexity detected"
exit 1
Expand Down
129 changes: 103 additions & 26 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ const (
canNotConnectToDataStorageMessage = "Can not connect to data storage"
unableToCloseDBRowsHandle = "Unable to close the DB rows handle"
connectionNotEstablished = "Connection to database was not established"
reportedMsg = "reported"
lastCheckedMsg = "lastChecked"
ageMsg = "age"
reportsCountMsg = "reports count"
)

// Other messages
Expand All @@ -67,7 +71,7 @@ const (

// SQL commands
const (
selectOldReports = `
selectOldOCPReports = `
SELECT cluster, reported_at, last_checked_at
FROM report
WHERE reported_at < NOW() - $1::INTERVAL
Expand All @@ -84,6 +88,12 @@ const (
FROM consumer_error
WHERE consumed_at < NOW() - $1::INTERVAL
ORDER BY consumed_at`

selectOldDVOReports = `
SELECT org_id, cluster_id, reported_at, last_checked_at
FROM dvo_report
WHERE reported_at < NOW() - $1::INTERVAL
ORDER BY reported_at`
)

// DB schemas
Expand Down Expand Up @@ -316,7 +326,7 @@ func createOutputFile(output string) (*os.File, *bufio.Writer) {

// displayAllOldRecords function read all old records, ie. records that are
// older than the specified time duration. Those records are simply displayed.
func displayAllOldRecords(connection *sql.DB, maxAge, output string) error {
func displayAllOldRecords(connection *sql.DB, maxAge, output string, schema string) error {
// check if connection has been initialized
if connection == nil {
log.Error().Msg(connectionNotEstablished)
Expand Down Expand Up @@ -345,25 +355,37 @@ func displayAllOldRecords(connection *sql.DB, maxAge, output string) error {
}
}()

// main function of this tool is ability to delete old reports
err := performListOfOldReports(connection, maxAge, writer)
// skip next operation on first error
if err != nil {
return err
}
switch schema {
case DBSchemaOCPRecommendations:
// main function of this tool is ability to delete old reports
err := performListOfOldOCPReports(connection, maxAge, writer)
// skip next operation on first error
if err != nil {
return err
}

// but we might be interested in other tables as well, especially advisor ratings
err = performListOfOldRatings(connection, maxAge)
// skip next operation on first error
if err != nil {
return err
}
// but we might be interested in other tables as well, especially advisor ratings
err = performListOfOldRatings(connection, maxAge)
// skip next operation on first error
if err != nil {
return err
}

// also but we might be interested in other consumer errors
err = performListOfOldConsumerErrors(connection, maxAge)
// skip next operation on first error
if err != nil {
return err
// also but we might be interested in other consumer errors
err = performListOfOldConsumerErrors(connection, maxAge)
// skip next operation on first error
if err != nil {
return err
}
case DBSchemaDVORecommendations:
// main function of this tool is ability to delete old reports
err := performListOfOldDVOReports(connection, maxAge, writer)
// skip next operation on first error
if err != nil {
return err
}
default:
return fmt.Errorf("Invalid database schema to be investigated: '%s'", schema)
}

return nil
Expand All @@ -389,10 +411,10 @@ func listOldDatabaseRecords(connection *sql.DB, maxAge string,
return nil
}

// performListOfOldReports read and displays old records read from reported_at
// performListOfOldOCPReports read and displays old records read from reported_at
// table
func performListOfOldReports(connection *sql.DB, maxAge string, writer *bufio.Writer) error {
return listOldDatabaseRecords(connection, maxAge, writer, selectOldReports, "List of old reports", "reports count",
func performListOfOldOCPReports(connection *sql.DB, maxAge string, writer *bufio.Writer) error {
return listOldDatabaseRecords(connection, maxAge, writer, selectOldOCPReports, "List of old OCP reports", reportsCountMsg,
func(rows *sql.Rows, writer *bufio.Writer) (int, error) {
// used to compute a real record age
now := time.Now()
Expand Down Expand Up @@ -426,10 +448,10 @@ func performListOfOldReports(connection *sql.DB, maxAge string, writer *bufio.Wr

// just print the report
log.Info().Str(clusterNameMsg, clusterName).
Str("reported", reportedF).
Str("lastChecked", lastCheckedF).
Int("age", age).
Msg("Old report")
Str(reportedMsg, reportedF).
Str(lastCheckedMsg, lastCheckedF).
Int(ageMsg, age).
Msg("Old OCP report")

if writer != nil {
_, err := fmt.Fprintf(writer, "%s,%s,%s,%d\n", clusterName, reportedF, lastCheckedF, age)
Expand All @@ -443,6 +465,61 @@ func performListOfOldReports(connection *sql.DB, maxAge string, writer *bufio.Wr
})
}

// performListOfOldDVOReports read and displays old records read from dvo_report
// table
func performListOfOldDVOReports(connection *sql.DB, maxAge string, writer *bufio.Writer) error {
return listOldDatabaseRecords(connection, maxAge, writer, selectOldDVOReports, "List of old DVO reports", reportsCountMsg,
func(rows *sql.Rows, writer *bufio.Writer) (int, error) {
// used to compute a real record age
now := time.Now()

// reports count
count := 0

// iterate over all old records
for rows.Next() {
var (
orgID int
clusterName string
reported time.Time
lastChecked time.Time
)

// read one old record from the report table
if err := rows.Scan(&orgID, &clusterName, &reported, &lastChecked); err != nil {
// close the result set in case of any error
if closeErr := rows.Close(); closeErr != nil {
log.Error().Err(closeErr).Msg(unableToCloseDBRowsHandle)
}
return count, err
}

// compute the real record age
age := int(math.Ceil(now.Sub(reported).Hours() / 24)) // in days

// prepare for the report
reportedF := reported.Format(time.RFC3339)
lastCheckedF := lastChecked.Format(time.RFC3339)

// just print the report
log.Info().Str(clusterNameMsg, clusterName).
Str(reportedMsg, reportedF).
Str(lastCheckedMsg, lastCheckedF).
Int(ageMsg, age).
Msg("Old DVO report")

if writer != nil {
_, err := fmt.Fprintf(writer, "%d,%s,%s,%s,%d\n", orgID, clusterName, reportedF, lastCheckedF, age)
if err != nil {
log.Error().Err(err).Msg(writeToFileMsg)
}
}
count++
}
return count, nil
})
}

// performListOfOldRatings read and displays old Advisor ratings read from
// advisor_ratings table
func performListOfOldRatings(connection *sql.DB, maxAge string) error {
Expand Down
Loading