cert-checker: use config log level and handle nil mariadb response (#6066)
- Fix cert-checker to use the syslog and stdout logging facilities it reads from the config file instead of having them hard-coded to zero. - Fix cert-checker to handle a nil response from mariadb if no records are found. - Fix comment in log.go to correctly describe when the initialize function and therefore default values would be used. Fixes #6067
This commit is contained in:
parent
8ec10c4848
commit
a2ff222fda
|
|
@ -4,7 +4,9 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/syslog"
|
||||
|
|
@ -80,7 +82,7 @@ type reportEntry struct {
|
|||
// out the saDbMap implementation.
|
||||
type certDB interface {
|
||||
Select(i interface{}, query string, args ...interface{}) ([]interface{}, error)
|
||||
SelectInt(query string, args ...interface{}) (int64, error)
|
||||
SelectNullInt(query string, args ...interface{}) (sql.NullInt64, error)
|
||||
}
|
||||
|
||||
type certChecker struct {
|
||||
|
|
@ -118,13 +120,19 @@ func (c *certChecker) getCerts(unexpiredOnly bool) error {
|
|||
args["now"] = c.clock.Now()
|
||||
}
|
||||
|
||||
initialID, err := c.dbMap.SelectInt(
|
||||
sni, err := c.dbMap.SelectNullInt(
|
||||
"SELECT MIN(id) FROM certificates WHERE issued >= :issued AND expires >= :now",
|
||||
args,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !sni.Valid {
|
||||
// a nil response was returned by the DB, so return error and fail
|
||||
return errors.New("the SELECT query resulted in a NULL response from the DB")
|
||||
}
|
||||
|
||||
initialID := sni.Int64
|
||||
if initialID > 0 {
|
||||
// decrement the initial ID so that we select below as we aren't using >=
|
||||
initialID -= 1
|
||||
|
|
@ -368,8 +376,12 @@ func main() {
|
|||
syslogger, err := syslog.Dial("", "", syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
|
||||
cmd.FailOnError(err, "Failed to dial syslog")
|
||||
|
||||
logger, err := blog.New(syslogger, 0, 0)
|
||||
cmd.FailOnError(err, "Failed to construct logger")
|
||||
syslogLevel := int(syslog.LOG_INFO)
|
||||
if config.Syslog.SyslogLevel != 0 {
|
||||
syslogLevel = config.Syslog.SyslogLevel
|
||||
}
|
||||
logger, err := blog.New(syslogger, config.Syslog.StdoutLevel, syslogLevel)
|
||||
cmd.FailOnError(err, "Could not connect to Syslog")
|
||||
|
||||
err = blog.Set(logger)
|
||||
cmd.FailOnError(err, "Failed to set audit logger")
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"database/sql"
|
||||
"encoding/asn1"
|
||||
"encoding/pem"
|
||||
"io/ioutil"
|
||||
|
|
@ -380,8 +381,12 @@ type mismatchedCountDB struct{}
|
|||
// `getCerts` calls `SelectInt` first to determine how many rows there are
|
||||
// matching the `getCertsCountQuery` criteria. For this mock we return
|
||||
// a non-zero number
|
||||
func (db mismatchedCountDB) SelectInt(_ string, _ ...interface{}) (int64, error) {
|
||||
return 99999, nil
|
||||
func (db mismatchedCountDB) SelectNullInt(_ string, _ ...interface{}) (sql.NullInt64, error) {
|
||||
return sql.NullInt64{
|
||||
Int64: 99999,
|
||||
Valid: true,
|
||||
},
|
||||
nil
|
||||
}
|
||||
|
||||
// `getCerts` then calls `Select` to retrieve the Certificate rows. We pull
|
||||
|
|
@ -422,6 +427,33 @@ func TestGetCertsEmptyResults(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Failed to retrieve certificates")
|
||||
}
|
||||
|
||||
// emptyDB is a certDB object with methods used for testing that 'null'
|
||||
// responses received from the database are handled properly.
|
||||
type emptyDB struct {
|
||||
certDB
|
||||
}
|
||||
|
||||
// SelectNullInt is a method that returns a false sql.NullInt64 struct to
|
||||
// mock a null DB response
|
||||
func (db emptyDB) SelectNullInt(_ string, _ ...interface{}) (sql.NullInt64, error) {
|
||||
return sql.NullInt64{Valid: false},
|
||||
nil
|
||||
}
|
||||
|
||||
// TestGetCertsNullResults tests that a null response from the database will
|
||||
// be handled properly. It uses the emptyDB above to mock the response
|
||||
// expected if the DB finds no certificates to match the SELECT query and
|
||||
// should return an error.
|
||||
func TestGetCertsNullResults(t *testing.T) {
|
||||
saDbMap, err := sa.NewDbMap(vars.DBConnSA, sa.DbSettings{})
|
||||
test.AssertNotError(t, err, "Couldn't connect to database")
|
||||
checker := newChecker(saDbMap, clock.NewFake(), pa, kp, time.Hour, testValidityDurations)
|
||||
checker.dbMap = emptyDB{}
|
||||
|
||||
err = checker.getCerts(false)
|
||||
test.AssertError(t, err, "Should have gotten error from empty DB")
|
||||
}
|
||||
|
||||
func TestSaveReport(t *testing.T) {
|
||||
r := report{
|
||||
begin: time.Time{},
|
||||
|
|
|
|||
|
|
@ -65,10 +65,9 @@ func New(log *syslog.Writer, stdoutLogLevel int, syslogLogLevel int) (Logger, er
|
|||
}, nil
|
||||
}
|
||||
|
||||
// initialize should only be used in unit tests.
|
||||
// initialize is used in unit tests and called by `Get` before the logger
|
||||
// is fully set up.
|
||||
func initialize() {
|
||||
// defaultPriority is never used because we always use specific priority-based
|
||||
// logging methods.
|
||||
const defaultPriority = syslog.LOG_INFO | syslog.LOG_LOCAL0
|
||||
syslogger, err := syslog.Dial("", "", defaultPriority, "test")
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in New Issue