Browse Source

switch to utc time everywhere (#1167)

* switch to utc time everywhere


Co-authored-by: alteredCoder <kevin@crowdsec.net>
Thibault "bui" Koechlin 3 years ago
parent
commit
cc1ab8c50d
74 changed files with 1106 additions and 391 deletions
  1. 2 2
      cmd/crowdsec-cli/alerts.go
  2. 2 7
      cmd/crowdsec-cli/capi.go
  3. 6 6
      cmd/crowdsec-cli/decisions.go
  4. 1 7
      cmd/crowdsec-cli/lapi.go
  5. 1 1
      cmd/crowdsec/serve.go
  6. 4 4
      pkg/acquisition/modules/cloudwatch/cloudwatch.go
  7. 2 2
      pkg/acquisition/modules/cloudwatch/cloudwatch_test.go
  8. 3 3
      pkg/acquisition/modules/docker/docker.go
  9. 1 1
      pkg/acquisition/modules/file/file.go
  10. 1 1
      pkg/acquisition/modules/journalctl/journalctl.go
  11. 1 1
      pkg/acquisition/modules/kinesis/kinesis.go
  12. 1 1
      pkg/acquisition/modules/kinesis/kinesis_test.go
  13. 2 2
      pkg/acquisition/modules/syslog/internal/syslogserver.go
  14. 1 1
      pkg/acquisition/modules/syslog/syslog.go
  15. 1 1
      pkg/apiclient/auth.go
  16. 13 0
      pkg/apiclient/client_http.go
  17. 2 2
      pkg/apiserver/alerts_test.go
  18. 3 3
      pkg/apiserver/apic.go
  19. 1 1
      pkg/apiserver/controllers/v1/alerts.go
  20. 3 3
      pkg/apiserver/controllers/v1/decisions.go
  21. 14 14
      pkg/apiserver/decisions_test.go
  22. 7 7
      pkg/database/alerts.go
  23. 8 8
      pkg/database/decisions.go
  24. 14 8
      pkg/database/ent/alert.go
  25. 4 0
      pkg/database/ent/alert/alert.go
  26. 28 0
      pkg/database/ent/alert/where.go
  27. 2 8
      pkg/database/ent/alert_create.go
  28. 62 20
      pkg/database/ent/alert_update.go
  29. 14 8
      pkg/database/ent/bouncer.go
  30. 4 0
      pkg/database/ent/bouncer/bouncer.go
  31. 28 0
      pkg/database/ent/bouncer/where.go
  32. 2 8
      pkg/database/ent/bouncer_create.go
  33. 62 20
      pkg/database/ent/bouncer_update.go
  34. 14 8
      pkg/database/ent/decision.go
  35. 4 0
      pkg/database/ent/decision/decision.go
  36. 28 0
      pkg/database/ent/decision/where.go
  37. 2 8
      pkg/database/ent/decision_create.go
  38. 62 20
      pkg/database/ent/decision_update.go
  39. 14 8
      pkg/database/ent/event.go
  40. 4 0
      pkg/database/ent/event/event.go
  41. 28 0
      pkg/database/ent/event/where.go
  42. 2 8
      pkg/database/ent/event_create.go
  43. 62 20
      pkg/database/ent/event_update.go
  44. 21 12
      pkg/database/ent/machine.go
  45. 6 0
      pkg/database/ent/machine/machine.go
  46. 28 0
      pkg/database/ent/machine/where.go
  47. 3 9
      pkg/database/ent/machine_create.go
  48. 70 36
      pkg/database/ent/machine_update.go
  49. 14 8
      pkg/database/ent/meta.go
  50. 4 0
      pkg/database/ent/meta/meta.go
  51. 28 0
      pkg/database/ent/meta/where.go
  52. 2 8
      pkg/database/ent/meta_create.go
  53. 62 20
      pkg/database/ent/meta_update.go
  54. 12 12
      pkg/database/ent/migrate/schema.go
  55. 249 15
      pkg/database/ent/mutation.go
  56. 26 0
      pkg/database/ent/runtime.go
  57. 7 6
      pkg/database/ent/schema/alert.go
  58. 7 6
      pkg/database/ent/schema/bouncer.go
  59. 5 4
      pkg/database/ent/schema/decision.go
  60. 5 4
      pkg/database/ent/schema/event.go
  61. 7 5
      pkg/database/ent/schema/machine.go
  62. 5 4
      pkg/database/ent/schema/meta.go
  63. 2 2
      pkg/database/machines.go
  64. 1 1
      pkg/exprhelpers/exprlib.go
  65. 1 1
      pkg/exprhelpers/exprlib_test.go
  66. 4 4
      pkg/leakybucket/bucket.go
  67. 2 2
      pkg/leakybucket/manager_run.go
  68. 2 2
      pkg/leakybucket/manager_run_test.go
  69. 1 1
      pkg/leakybucket/overflows.go
  70. 4 4
      pkg/leakybucket/trigger.go
  71. 2 2
      pkg/parser/enrich_date.go
  72. 1 1
      pkg/parser/runtime.go
  73. 1 0
      pkg/time/rate/rate_test.go
  74. 4 0
      pkg/types/utils.go

+ 2 - 2
cmd/crowdsec-cli/alerts.go

@@ -157,8 +157,8 @@ func DisplayOneAlert(alert *models.Alert, withDetail bool) error {
 			if err != nil {
 				log.Errorf(err.Error())
 			}
-			expire := time.Now().Add(parsedDuration)
-			if time.Now().After(expire) {
+			expire := time.Now().UTC().Add(parsedDuration)
+			if time.Now().UTC().After(expire) {
 				continue
 			}
 			foundActive = true

+ 2 - 7
cmd/crowdsec-cli/capi.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"fmt"
 	"io/ioutil"
-	"net/http/httputil"
 	"net/url"
 
 	"github.com/crowdsecurity/crowdsec/pkg/apiclient"
@@ -155,17 +154,13 @@ func NewCapiCmd() *cobra.Command {
 			}
 			log.Infof("Loaded credentials from %s", csConfig.API.Server.OnlineClient.CredentialsFilePath)
 			log.Infof("Trying to authenticate with username %s on %s", csConfig.API.Server.OnlineClient.Credentials.Login, apiurl)
-			resp, err := Client.Auth.AuthenticateWatcher(context.Background(), t)
+			_, err = Client.Auth.AuthenticateWatcher(context.Background(), t)
 			if err != nil {
 				log.Fatalf("Failed to authenticate to Central API (CAPI) : %s", err)
 			} else {
 				log.Infof("You can successfully interact with Central API (CAPI)")
 			}
-			for k, v := range resp.Response.Header {
-				log.Debugf("[headers] %s : %s", k, v)
-			}
-			dump, _ := httputil.DumpResponse(resp.Response, true)
-			log.Debugf("Response: %s", string(dump))
+
 		},
 	}
 	cmdCapi.AddCommand(cmdCapiStatus)

+ 6 - 6
cmd/crowdsec-cli/decisions.go

@@ -310,9 +310,9 @@ cscli decisions add --scope username --value foobar
 			eventsCount := int32(1)
 			empty := ""
 			simulated := false
-			startAt := time.Now().Format(time.RFC3339)
-			stopAt := time.Now().Format(time.RFC3339)
-			createdAt := time.Now().Format(time.RFC3339)
+			startAt := time.Now().UTC().Format(time.RFC3339)
+			stopAt := time.Now().UTC().Format(time.RFC3339)
+			createdAt := time.Now().UTC().Format(time.RFC3339)
 
 			/*take care of shorthand options*/
 			if err := manageCliDecisionAlerts(&addIP, &addRange, &addScope, &addValue); err != nil {
@@ -582,7 +582,7 @@ decisions.json :
 			}
 			alerts := models.AddAlertsRequest{}
 			importAlert := models.Alert{
-				CreatedAt: time.Now().Format(time.RFC3339),
+				CreatedAt: time.Now().UTC().Format(time.RFC3339),
 				Scenario:  types.StrPtr(fmt.Sprintf("add: %d IPs", len(decisionsList))),
 				Message:   types.StrPtr(""),
 				Events:    []*models.Event{},
@@ -590,8 +590,8 @@ decisions.json :
 					Scope: types.StrPtr("cscli/manual-import"),
 					Value: types.StrPtr(""),
 				},
-				StartAt:         types.StrPtr(time.Now().Format(time.RFC3339)),
-				StopAt:          types.StrPtr(time.Now().Format(time.RFC3339)),
+				StartAt:         types.StrPtr(time.Now().UTC().Format(time.RFC3339)),
+				StopAt:          types.StrPtr(time.Now().UTC().Format(time.RFC3339)),
 				Capacity:        types.Int32Ptr(0),
 				Simulated:       types.BoolPtr(false),
 				EventsCount:     types.Int32Ptr(int32(len(decisionsList))),

+ 1 - 7
cmd/crowdsec-cli/lapi.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"fmt"
 	"io/ioutil"
-	"net/http/httputil"
 	"net/url"
 	"strings"
 
@@ -166,17 +165,12 @@ Keep in mind the machine needs to be validated by an administrator on LAPI side
 			}
 			log.Infof("Loaded credentials from %s", csConfig.API.Client.CredentialsFilePath)
 			log.Infof("Trying to authenticate with username %s on %s", login, apiurl)
-			resp, err := Client.Auth.AuthenticateWatcher(context.Background(), t)
+			_, err = Client.Auth.AuthenticateWatcher(context.Background(), t)
 			if err != nil {
 				log.Fatalf("Failed to authenticate to Local API (LAPI) : %s", err)
 			} else {
 				log.Infof("You can successfully interact with Local API (LAPI)")
 			}
-			for k, v := range resp.Response.Header {
-				log.Debugf("[headers] %s : %s", k, v)
-			}
-			dump, _ := httputil.DumpResponse(resp.Response, true)
-			log.Debugf("Response: %s", string(dump))
 		},
 	}
 	cmdLapi.AddCommand(cmdLapiStatus)

+ 1 - 1
cmd/crowdsec/serve.go

@@ -27,7 +27,7 @@ func debugHandler(sig os.Signal, cConfig *csconfig.Config) error {
 		log.Warningf("Failed to shut down routines: %s", err)
 	}
 	//todo : properly stop acquis with the tail readers
-	if tmpFile, err = leaky.DumpBucketsStateAt(time.Now(), cConfig.Crowdsec.BucketStateDumpDir, buckets); err != nil {
+	if tmpFile, err = leaky.DumpBucketsStateAt(time.Now().UTC(), cConfig.Crowdsec.BucketStateDumpDir, buckets); err != nil {
 		log.Warningf("Failed dumping bucket state : %s", err)
 	}
 	if err := leaky.ShutdownAllBuckets(buckets); err != nil {

+ 4 - 4
pkg/acquisition/modules/cloudwatch/cloudwatch.go

@@ -287,7 +287,7 @@ func (cw *CloudwatchSource) WatchLogGroupForStreams(out chan LogStreamTailConfig
 								//TBD : verify that this is correct : Unix 2nd arg expects Nanoseconds, and have a code that is more explicit.
 								LastIngestionTime := time.Unix(0, *event.LastIngestionTime*int64(time.Millisecond))
 								if LastIngestionTime.Before(oldest) {
-									cw.logger.Tracef("stop iteration, %s reached oldest age, stop (%s < %s)", *event.LogStreamName, LastIngestionTime, time.Now().Add(-*cw.Config.MaxStreamAge))
+									cw.logger.Tracef("stop iteration, %s reached oldest age, stop (%s < %s)", *event.LogStreamName, LastIngestionTime, time.Now().UTC().Add(-*cw.Config.MaxStreamAge))
 									hasMoreStreams = false
 									return false
 								}
@@ -408,7 +408,7 @@ func (cw *CloudwatchSource) LogStreamManager(in chan LogStreamTailConfig, outCha
 
 func (cw *CloudwatchSource) TailLogStream(cfg *LogStreamTailConfig, outChan chan types.Event) error {
 	var startFrom *string
-	var lastReadMessage time.Time = time.Now()
+	var lastReadMessage time.Time = time.Now().UTC()
 	ticker := time.NewTicker(cfg.PollStreamInterval)
 	//resume at existing index if we already had
 	streamIndexMutex.Lock()
@@ -450,7 +450,7 @@ func (cw *CloudwatchSource) TailLogStream(cfg *LogStreamTailConfig, outChan chan
 							hasMorePages = false
 						}
 						if len(page.Events) > 0 {
-							lastReadMessage = time.Now()
+							lastReadMessage = time.Now().UTC()
 						}
 						for _, event := range page.Events {
 							evt, err := cwLogToEvent(event, cfg)
@@ -669,7 +669,7 @@ func cwLogToEvent(log *cloudwatchlogs.OutputLogEvent, cfg *LogStreamTailConfig)
 	}
 	l.Raw = msg
 	l.Labels = cfg.Labels
-	l.Time = time.Now()
+	l.Time = time.Now().UTC()
 	l.Src = fmt.Sprintf("%s/%s", cfg.GroupName, cfg.StreamName)
 	l.Process = true
 	l.Module = "cloudwatch"

+ 2 - 2
pkg/acquisition/modules/cloudwatch/cloudwatch_test.go

@@ -718,7 +718,7 @@ func TestOneShotAcquisition(t *testing.T) {
 					LogEvents: []*cloudwatchlogs.InputLogEvent{
 						&cloudwatchlogs.InputLogEvent{
 							Message:   aws.String("test_message_1"),
-							Timestamp: aws.Int64(time.Now().Add(-(2 * time.Hour)).UTC().Unix() * 1000),
+							Timestamp: aws.Int64(time.Now().UTC().Add(-(2 * time.Hour)).UTC().Unix() * 1000),
 						},
 					},
 				}); err != nil {
@@ -746,7 +746,7 @@ func TestOneShotAcquisition(t *testing.T) {
 					LogEvents: []*cloudwatchlogs.InputLogEvent{
 						&cloudwatchlogs.InputLogEvent{
 							Message:   aws.String("test_message_3"),
-							Timestamp: aws.Int64(time.Now().Add(-(3 * time.Hour)).UTC().Unix() * 1000),
+							Timestamp: aws.Int64(time.Now().UTC().Add(-(3 * time.Hour)).UTC().Unix() * 1000),
 						},
 					},
 				}); err != nil {

+ 3 - 3
pkg/acquisition/modules/docker/docker.go

@@ -115,7 +115,7 @@ func (d *DockerSource) Configure(Config []byte, logger *log.Entry) error {
 	}
 
 	if d.Config.Since == "" {
-		d.Config.Since = time.Now().Format(time.RFC3339)
+		d.Config.Since = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	d.containerLogsOptions = &dockerTypes.ContainerLogsOptions{
@@ -295,7 +295,7 @@ func (d *DockerSource) OneShotAcquisition(out chan types.Event, t *tomb.Tomb) er
 				l := types.Line{}
 				l.Raw = line
 				l.Labels = d.Config.Labels
-				l.Time = time.Now()
+				l.Time = time.Now().UTC()
 				l.Src = containerConfig.Name
 				l.Process = true
 				l.Module = d.GetName()
@@ -475,7 +475,7 @@ func (d *DockerSource) TailDocker(container *ContainerConfig, outChan chan types
 			l := types.Line{}
 			l.Raw = line
 			l.Labels = d.Config.Labels
-			l.Time = time.Now()
+			l.Time = time.Now().UTC()
 			l.Src = container.Name
 			l.Process = true
 			l.Module = d.GetName()

+ 1 - 1
pkg/acquisition/modules/file/file.go

@@ -417,7 +417,7 @@ func (f *FileSource) readFile(filename string, out chan types.Event, t *tomb.Tom
 		logger.Debugf("line %s", scanner.Text())
 		l := types.Line{}
 		l.Raw = scanner.Text()
-		l.Time = time.Now()
+		l.Time = time.Now().UTC()
 		l.Src = filename
 		l.Labels = f.config.Labels
 		l.Process = true

+ 1 - 1
pkg/acquisition/modules/journalctl/journalctl.go

@@ -126,7 +126,7 @@ func (j *JournalCtlSource) runJournalCtl(out chan types.Event, t *tomb.Tomb) err
 			l.Raw = stdoutLine
 			logger.Debugf("getting one line : %s", l.Raw)
 			l.Labels = j.config.Labels
-			l.Time = time.Now()
+			l.Time = time.Now().UTC()
 			l.Src = j.src
 			l.Process = true
 			l.Module = j.GetName()

+ 1 - 1
pkg/acquisition/modules/kinesis/kinesis.go

@@ -288,7 +288,7 @@ func (k *KinesisSource) ParseAndPushRecords(records []*kinesis.Record, out chan
 			l := types.Line{}
 			l.Raw = event.Message
 			l.Labels = k.Config.Labels
-			l.Time = time.Now()
+			l.Time = time.Now().UTC()
 			l.Process = true
 			l.Module = k.GetName()
 			if k.Config.StreamARN != "" {

+ 1 - 1
pkg/acquisition/modules/kinesis/kinesis_test.go

@@ -43,7 +43,7 @@ func GenSubObject(i int) []byte {
 			{
 				ID:        "testid",
 				Message:   fmt.Sprintf("%d", i),
-				Timestamp: time.Now().Unix(),
+				Timestamp: time.Now().UTC().Unix(),
 			},
 		},
 	}

+ 2 - 2
pkg/acquisition/modules/syslog/internal/syslogserver.go

@@ -43,7 +43,7 @@ func (s *SyslogServer) Listen(listenAddr string, port int) error {
 	if err != nil {
 		return errors.Wrap(err, "could not set readbuffer on UDP socket")
 	}
-	err = s.udpConn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+	err = s.udpConn.SetReadDeadline(time.Now().UTC().Add(100 * time.Millisecond))
 	if err != nil {
 		return errors.Wrap(err, "could not set read deadline on UDP socket")
 	}
@@ -77,7 +77,7 @@ func (s *SyslogServer) StartServer() *tomb.Tomb {
 				if err == nil {
 					s.channel <- SyslogMessage{Message: b[:n], Client: strings.Split(addr.String(), ":")[0]}
 				}
-				err = s.udpConn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+				err = s.udpConn.SetReadDeadline(time.Now().UTC().Add(100 * time.Millisecond))
 				if err != nil {
 					return err
 				}

+ 1 - 1
pkg/acquisition/modules/syslog/syslog.go

@@ -143,7 +143,7 @@ func (s *SyslogSource) buildLogFromSyslog(ts *time.Time, hostname *string,
 		ret += ts.Format("Jan 2 15:04:05")
 	} else {
 		s.logger.Tracef("%s - missing TS", *msg)
-		ret += time.Now().Format("Jan 2 15:04:05")
+		ret += time.Now().UTC().Format("Jan 2 15:04:05")
 	}
 	if hostname != nil {
 		ret += " " + *hostname

+ 1 - 1
pkg/apiclient/auth.go

@@ -170,7 +170,7 @@ func (t *JWTTransport) refreshJwtToken() error {
 
 // RoundTrip implements the RoundTripper interface.
 func (t *JWTTransport) RoundTrip(req *http.Request) (*http.Response, error) {
-	if t.token == "" || t.Expiration.Add(-time.Minute).Before(time.Now()) {
+	if t.token == "" || t.Expiration.Add(-time.Minute).Before(time.Now().UTC()) {
 		if err := t.refreshJwtToken(); err != nil {
 			return nil, err
 		}

+ 13 - 0
pkg/apiclient/client_http.go

@@ -8,8 +8,11 @@ import (
 	"fmt"
 	"io"
 	"net/http"
+	"net/http/httputil"
 	"net/url"
 	"strings"
+
+	log "github.com/sirupsen/logrus"
 )
 
 func (c *ApiClient) NewRequest(method, url string, body interface{}) (*http.Request, error) {
@@ -60,6 +63,7 @@ func (c *ApiClient) Do(ctx context.Context, req *http.Request, v interface{}) (*
 	if resp != nil && resp.Body != nil {
 		defer resp.Body.Close()
 	}
+
 	if err != nil {
 		// If we got an error, and the context has been canceled,
 		// the context's error is probably more useful.
@@ -81,6 +85,15 @@ func (c *ApiClient) Do(ctx context.Context, req *http.Request, v interface{}) (*
 		return newResponse(resp), err
 	}
 
+	for k, v := range resp.Header {
+		log.Debugf("[headers] %s : %s", k, v)
+	}
+
+	dump, err := httputil.DumpResponse(resp, true)
+	if err == nil {
+		log.Debugf("Response: %s", string(dump))
+	}
+
 	response := newResponse(resp)
 
 	err = CheckResponse(resp)

+ 2 - 2
pkg/apiserver/alerts_test.go

@@ -201,8 +201,8 @@ func TestAlertListFilters(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)

+ 3 - 3
pkg/apiserver/apic.go

@@ -266,7 +266,7 @@ func (a *apic) PullTop() error {
 	/*only pull community blocklist if it's older than 1h30 */
 	alerts := a.dbClient.Ent.Alert.Query()
 	alerts = alerts.Where(alert.HasDecisionsWith(decision.OriginEQ(database.CapiMachineID)))
-	alerts = alerts.Where(alert.CreatedAtGTE(time.Now().Add(-time.Duration(1*time.Hour + 30*time.Minute))))
+	alerts = alerts.Where(alert.CreatedAtGTE(time.Now().UTC().Add(-time.Duration(1*time.Hour + 30*time.Minute))))
 	count, err := alerts.Count(a.dbClient.CTX)
 	if err != nil {
 		return errors.Wrap(err, "while looking for CAPI alert")
@@ -379,8 +379,8 @@ func (a *apic) PullTop() error {
 				log.Warningf("unknown origin %s", *decision.Origin)
 			}
 			newAlert.Source.Value = types.StrPtr("")
-			newAlert.StartAt = types.StrPtr(time.Now().Format(time.RFC3339))
-			newAlert.StopAt = types.StrPtr(time.Now().Format(time.RFC3339))
+			newAlert.StartAt = types.StrPtr(time.Now().UTC().Format(time.RFC3339))
+			newAlert.StopAt = types.StrPtr(time.Now().UTC().Format(time.RFC3339))
 			newAlert.Capacity = types.Int32Ptr(0)
 			newAlert.Simulated = types.BoolPtr(false)
 			newAlert.EventsCount = types.Int32Ptr(int32(len(data.New)))

+ 1 - 1
pkg/apiserver/controllers/v1/alerts.go

@@ -73,7 +73,7 @@ func FormatOneAlert(alert *ent.Alert) *models.Alert {
 		})
 	}
 	for _, decisionItem := range alert.Edges.Decisions {
-		duration := decisionItem.Until.Sub(time.Now()).String()
+		duration := decisionItem.Until.Sub(time.Now().UTC()).String()
 		outputAlert.Decisions = append(outputAlert.Decisions, &models.Decision{
 			Duration:  &duration, // transform into time.Time ?
 			Scenario:  &decisionItem.Scenario,

+ 3 - 3
pkg/apiserver/controllers/v1/decisions.go

@@ -17,7 +17,7 @@ import (
 func FormatDecisions(decisions []*ent.Decision) ([]*models.Decision, error) {
 	var results []*models.Decision
 	for _, dbDecision := range decisions {
-		duration := dbDecision.Until.Sub(time.Now()).String()
+		duration := dbDecision.Until.Sub(time.Now().UTC()).String()
 		decision := models.Decision{
 			ID:       int64(dbDecision.ID),
 			Duration: &duration,
@@ -164,7 +164,7 @@ func (c *Controller) StreamDecision(gctx *gin.Context) {
 				return
 			}
 
-			if err := c.DBClient.UpdateBouncerLastPull(time.Now(), bouncerInfo.ID); err != nil {
+			if err := c.DBClient.UpdateBouncerLastPull(time.Now().UTC(), bouncerInfo.ID); err != nil {
 				log.Errorf("unable to update bouncer '%s' pull: %v", bouncerInfo.Name, err)
 				gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
 				return
@@ -206,7 +206,7 @@ func (c *Controller) StreamDecision(gctx *gin.Context) {
 		return
 	}
 
-	if err := c.DBClient.UpdateBouncerLastPull(time.Now(), bouncerInfo.ID); err != nil {
+	if err := c.DBClient.UpdateBouncerLastPull(time.Now().UTC(), bouncerInfo.ID); err != nil {
 		log.Errorf("unable to update bouncer '%s' pull: %v", bouncerInfo.Name, err)
 		gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
 		return

+ 14 - 14
pkg/apiserver/decisions_test.go

@@ -32,8 +32,8 @@ func TestDeleteDecisionRange(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)
@@ -88,8 +88,8 @@ func TestDeleteDecisionFilter(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)
@@ -144,8 +144,8 @@ func TestGetDecisionFilters(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)
@@ -231,8 +231,8 @@ func TestGetDecision(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)
@@ -288,8 +288,8 @@ func TestDeleteDecisionByID(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)
@@ -347,8 +347,8 @@ func TestDeleteDecision(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)
@@ -398,8 +398,8 @@ func TestStreamDecision(t *testing.T) {
 	}
 
 	for _, alert := range alerts {
-		*alert.StartAt = time.Now().Format(time.RFC3339)
-		*alert.StopAt = time.Now().Format(time.RFC3339)
+		*alert.StartAt = time.Now().UTC().Format(time.RFC3339)
+		*alert.StopAt = time.Now().UTC().Format(time.RFC3339)
 	}
 
 	alertContent, err := json.Marshal(alerts)

+ 7 - 7
pkg/database/alerts.go

@@ -142,7 +142,7 @@ func (c *Client) UpdateCommunityBlocklist(alertItem *models.Alert) (int, int, in
 	ts, err := time.Parse(time.RFC3339, *alertItem.StopAt)
 	if err != nil {
 		c.Log.Errorf("While parsing StartAt of item %s : %s", *alertItem.StopAt, err)
-		ts = time.Now()
+		ts = time.Now().UTC()
 	}
 
 	alertB := c.Ent.Alert.
@@ -409,7 +409,7 @@ func (c *Client) CreateAlertBulk(machineId string, alertList []*models.Alert) ([
 		ts, err := time.Parse(time.RFC3339, *alertItem.StopAt)
 		if err != nil {
 			c.Log.Errorf("While parsing StartAt of item %s : %s", *alertItem.StopAt, err)
-			ts = time.Now()
+			ts = time.Now().UTC()
 		}
 
 		decisions = make([]*ent.Decision, 0)
@@ -594,7 +594,7 @@ func BuildAlertRequestFromFilter(alerts *ent.AlertQuery, filter map[string][]str
 			if err != nil {
 				return nil, errors.Wrap(err, "while parsing duration")
 			}
-			since := time.Now().Add(-duration)
+			since := time.Now().UTC().Add(-duration)
 			if since.IsZero() {
 				return nil, fmt.Errorf("Empty time now() - %s", since.String())
 			}
@@ -604,7 +604,7 @@ func BuildAlertRequestFromFilter(alerts *ent.AlertQuery, filter map[string][]str
 			if err != nil {
 				return nil, errors.Wrap(err, "while parsing duration")
 			}
-			since := time.Now().Add(-duration)
+			since := time.Now().UTC().Add(-duration)
 			if since.IsZero() {
 				return nil, fmt.Errorf("Empty time now() - %s", since.String())
 			}
@@ -614,7 +614,7 @@ func BuildAlertRequestFromFilter(alerts *ent.AlertQuery, filter map[string][]str
 			if err != nil {
 				return nil, errors.Wrap(err, "while parsing duration")
 			}
-			until := time.Now().Add(-duration)
+			until := time.Now().UTC().Add(-duration)
 			if until.IsZero() {
 				return nil, fmt.Errorf("Empty time now() - %s", until.String())
 			}
@@ -634,7 +634,7 @@ func BuildAlertRequestFromFilter(alerts *ent.AlertQuery, filter map[string][]str
 				return nil, errors.Wrapf(ParseType, "'%s' is not a boolean: %s", value[0], err)
 			}
 			if hasActiveDecision {
-				alerts = alerts.Where(alert.HasDecisionsWith(decision.UntilGTE(time.Now())))
+				alerts = alerts.Where(alert.HasDecisionsWith(decision.UntilGTE(time.Now().UTC())))
 			} else {
 				alerts = alerts.Where(alert.Not(alert.HasDecisions()))
 			}
@@ -874,7 +874,7 @@ func (c *Client) FlushOrphans() {
 	}
 
 	events_count, err = c.Ent.Decision.Delete().Where(
-		decision.Not(decision.HasOwner())).Where(decision.UntilLTE(time.Now())).Exec(c.CTX)
+		decision.Not(decision.HasOwner())).Where(decision.UntilLTE(time.Now().UTC())).Exec(c.CTX)
 
 	if err != nil {
 		c.Log.Warningf("error while deleting orphan decisions : %s", err)

+ 8 - 8
pkg/database/decisions.go

@@ -144,7 +144,7 @@ func (c *Client) QueryDecisionWithFilter(filter map[string][]string) ([]*ent.Dec
 	var err error
 
 	decisions := c.Ent.Decision.Query().
-		Where(decision.UntilGTE(time.Now()))
+		Where(decision.UntilGTE(time.Now().UTC()))
 
 	decisions, err = BuildDecisionRequestWithFilter(decisions, filter)
 	if err != nil {
@@ -171,7 +171,7 @@ func (c *Client) QueryDecisionWithFilter(filter map[string][]string) ([]*ent.Dec
 }
 
 func (c *Client) QueryAllDecisionsWithFilters(filters map[string][]string) ([]*ent.Decision, error) {
-	query := c.Ent.Decision.Query().Where(decision.UntilGT(time.Now()))
+	query := c.Ent.Decision.Query().Where(decision.UntilGT(time.Now().UTC()))
 	query, err := BuildDecisionRequestWithFilter(query, filters)
 
 	if err != nil {
@@ -188,7 +188,7 @@ func (c *Client) QueryAllDecisionsWithFilters(filters map[string][]string) ([]*e
 }
 
 func (c *Client) QueryExpiredDecisionsWithFilters(filters map[string][]string) ([]*ent.Decision, error) {
-	query := c.Ent.Decision.Query().Where(decision.UntilLT(time.Now()))
+	query := c.Ent.Decision.Query().Where(decision.UntilLT(time.Now().UTC()))
 	query, err := BuildDecisionRequestWithFilter(query, filters)
 
 	if err != nil {
@@ -204,7 +204,7 @@ func (c *Client) QueryExpiredDecisionsWithFilters(filters map[string][]string) (
 }
 
 func (c *Client) QueryExpiredDecisionsSinceWithFilters(since time.Time, filters map[string][]string) ([]*ent.Decision, error) {
-	query := c.Ent.Decision.Query().Where(decision.UntilLT(time.Now())).Where(decision.UntilGT(since))
+	query := c.Ent.Decision.Query().Where(decision.UntilLT(time.Now().UTC())).Where(decision.UntilGT(since))
 	query, err := BuildDecisionRequestWithFilter(query, filters)
 	if err != nil {
 		c.Log.Warningf("QueryExpiredDecisionsSinceWithFilters : %s", err)
@@ -221,7 +221,7 @@ func (c *Client) QueryExpiredDecisionsSinceWithFilters(since time.Time, filters
 }
 
 func (c *Client) QueryNewDecisionsSinceWithFilters(since time.Time, filters map[string][]string) ([]*ent.Decision, error) {
-	query := c.Ent.Decision.Query().Where(decision.CreatedAtGT(since)).Where(decision.UntilGT(time.Now()))
+	query := c.Ent.Decision.Query().Where(decision.CreatedAtGT(since)).Where(decision.UntilGT(time.Now().UTC()))
 	query, err := BuildDecisionRequestWithFilter(query, filters)
 	if err != nil {
 		c.Log.Warningf("QueryNewDecisionsSinceWithFilters : %s", err)
@@ -359,7 +359,7 @@ func (c *Client) SoftDeleteDecisionsWithFilter(filter map[string][]string) (stri
 	var contains bool = true
 	/*if contains is true, return bans that *contains* the given value (value is the inner)
 	  else, return bans that are *contained* by the given value (value is the outer)*/
-	decisions := c.Ent.Decision.Update().Where(decision.UntilGT(time.Now()))
+	decisions := c.Ent.Decision.Update().Where(decision.UntilGT(time.Now().UTC()))
 	for param, value := range filter {
 		switch param {
 		case "contains":
@@ -453,7 +453,7 @@ func (c *Client) SoftDeleteDecisionsWithFilter(filter map[string][]string) (stri
 	} else if ip_sz != 0 {
 		return "0", errors.Wrapf(InvalidFilter, "Unknown ip size %d", ip_sz)
 	}
-	nbDeleted, err := decisions.SetUntil(time.Now()).Save(c.CTX)
+	nbDeleted, err := decisions.SetUntil(time.Now().UTC()).Save(c.CTX)
 	if err != nil {
 		c.Log.Warningf("SoftDeleteDecisionsWithFilter : %s", err)
 		return "0", errors.Wrap(DeleteFail, "soft delete decisions with provided filter")
@@ -463,7 +463,7 @@ func (c *Client) SoftDeleteDecisionsWithFilter(filter map[string][]string) (stri
 
 //SoftDeleteDecisionByID set the expiration of a decision to now()
 func (c *Client) SoftDeleteDecisionByID(decisionID int) error {
-	nbUpdated, err := c.Ent.Decision.Update().Where(decision.IDEQ(decisionID)).SetUntil(time.Now()).Save(c.CTX)
+	nbUpdated, err := c.Ent.Decision.Update().Where(decision.IDEQ(decisionID)).SetUntil(time.Now().UTC()).Save(c.CTX)
 	if err != nil || nbUpdated == 0 {
 		c.Log.Warningf("SoftDeleteDecisionByID : %v (nb soft deleted: %d)", err, nbUpdated)
 		return errors.Wrapf(DeleteFail, "decision with id '%d' doesn't exist", decisionID)

+ 14 - 8
pkg/database/ent/alert.go

@@ -18,9 +18,9 @@ type Alert struct {
 	// ID of the ent.
 	ID int `json:"id,omitempty"`
 	// CreatedAt holds the value of the "created_at" field.
-	CreatedAt time.Time `json:"created_at,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
 	// UpdatedAt holds the value of the "updated_at" field.
-	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
 	// Scenario holds the value of the "scenario" field.
 	Scenario string `json:"scenario,omitempty"`
 	// BucketId holds the value of the "bucketId" field.
@@ -165,13 +165,15 @@ func (a *Alert) assignValues(columns []string, values []interface{}) error {
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field created_at", values[i])
 			} else if value.Valid {
-				a.CreatedAt = value.Time
+				a.CreatedAt = new(time.Time)
+				*a.CreatedAt = value.Time
 			}
 		case alert.FieldUpdatedAt:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
 			} else if value.Valid {
-				a.UpdatedAt = value.Time
+				a.UpdatedAt = new(time.Time)
+				*a.UpdatedAt = value.Time
 			}
 		case alert.FieldScenario:
 			if value, ok := values[i].(*sql.NullString); !ok {
@@ -348,10 +350,14 @@ func (a *Alert) String() string {
 	var builder strings.Builder
 	builder.WriteString("Alert(")
 	builder.WriteString(fmt.Sprintf("id=%v", a.ID))
-	builder.WriteString(", created_at=")
-	builder.WriteString(a.CreatedAt.Format(time.ANSIC))
-	builder.WriteString(", updated_at=")
-	builder.WriteString(a.UpdatedAt.Format(time.ANSIC))
+	if v := a.CreatedAt; v != nil {
+		builder.WriteString(", created_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := a.UpdatedAt; v != nil {
+		builder.WriteString(", updated_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
 	builder.WriteString(", scenario=")
 	builder.WriteString(a.Scenario)
 	builder.WriteString(", bucketId=")

+ 4 - 0
pkg/database/ent/alert/alert.go

@@ -146,8 +146,12 @@ func ValidColumn(column string) bool {
 var (
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
+	// UpdateDefaultCreatedAt holds the default value on update for the "created_at" field.
+	UpdateDefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
 	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultBucketId holds the default value on creation for the "bucketId" field.
 	DefaultBucketId string
 	// DefaultMessage holds the default value on creation for the "message" field.

+ 28 - 0
pkg/database/ent/alert/where.go

@@ -323,6 +323,20 @@ func CreatedAtLTE(v time.Time) predicate.Alert {
 	})
 }
 
+// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
+func CreatedAtIsNil() predicate.Alert {
+	return predicate.Alert(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldCreatedAt)))
+	})
+}
+
+// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
+func CreatedAtNotNil() predicate.Alert {
+	return predicate.Alert(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldCreatedAt)))
+	})
+}
+
 // UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
 func UpdatedAtEQ(v time.Time) predicate.Alert {
 	return predicate.Alert(func(s *sql.Selector) {
@@ -399,6 +413,20 @@ func UpdatedAtLTE(v time.Time) predicate.Alert {
 	})
 }
 
+// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
+func UpdatedAtIsNil() predicate.Alert {
+	return predicate.Alert(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldUpdatedAt)))
+	})
+}
+
+// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
+func UpdatedAtNotNil() predicate.Alert {
+	return predicate.Alert(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldUpdatedAt)))
+	})
+}
+
 // ScenarioEQ applies the EQ predicate on the "scenario" field.
 func ScenarioEQ(v string) predicate.Alert {
 	return predicate.Alert(func(s *sql.Selector) {

+ 2 - 8
pkg/database/ent/alert_create.go

@@ -495,12 +495,6 @@ func (ac *AlertCreate) defaults() {
 
 // check runs all checks and user-defined validators on the builder.
 func (ac *AlertCreate) check() error {
-	if _, ok := ac.mutation.CreatedAt(); !ok {
-		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)}
-	}
-	if _, ok := ac.mutation.UpdatedAt(); !ok {
-		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)}
-	}
 	if _, ok := ac.mutation.Scenario(); !ok {
 		return &ValidationError{Name: "scenario", err: errors.New(`ent: missing required field "scenario"`)}
 	}
@@ -540,7 +534,7 @@ func (ac *AlertCreate) createSpec() (*Alert, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: alert.FieldCreatedAt,
 		})
-		_node.CreatedAt = value
+		_node.CreatedAt = &value
 	}
 	if value, ok := ac.mutation.UpdatedAt(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -548,7 +542,7 @@ func (ac *AlertCreate) createSpec() (*Alert, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: alert.FieldUpdatedAt,
 		})
-		_node.UpdatedAt = value
+		_node.UpdatedAt = &value
 	}
 	if value, ok := ac.mutation.Scenario(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{

+ 62 - 20
pkg/database/ent/alert_update.go

@@ -37,11 +37,9 @@ func (au *AlertUpdate) SetCreatedAt(t time.Time) *AlertUpdate {
 	return au
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (au *AlertUpdate) SetNillableCreatedAt(t *time.Time) *AlertUpdate {
-	if t != nil {
-		au.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (au *AlertUpdate) ClearCreatedAt() *AlertUpdate {
+	au.mutation.ClearCreatedAt()
 	return au
 }
 
@@ -51,11 +49,9 @@ func (au *AlertUpdate) SetUpdatedAt(t time.Time) *AlertUpdate {
 	return au
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (au *AlertUpdate) SetNillableUpdatedAt(t *time.Time) *AlertUpdate {
-	if t != nil {
-		au.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (au *AlertUpdate) ClearUpdatedAt() *AlertUpdate {
+	au.mutation.ClearUpdatedAt()
 	return au
 }
 
@@ -611,6 +607,7 @@ func (au *AlertUpdate) Save(ctx context.Context) (int, error) {
 		err      error
 		affected int
 	)
+	au.defaults()
 	if len(au.hooks) == 0 {
 		affected, err = au.sqlSave(ctx)
 	} else {
@@ -659,6 +656,18 @@ func (au *AlertUpdate) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (au *AlertUpdate) defaults() {
+	if _, ok := au.mutation.CreatedAt(); !ok && !au.mutation.CreatedAtCleared() {
+		v := alert.UpdateDefaultCreatedAt()
+		au.mutation.SetCreatedAt(v)
+	}
+	if _, ok := au.mutation.UpdatedAt(); !ok && !au.mutation.UpdatedAtCleared() {
+		v := alert.UpdateDefaultUpdatedAt()
+		au.mutation.SetUpdatedAt(v)
+	}
+}
+
 func (au *AlertUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	_spec := &sqlgraph.UpdateSpec{
 		Node: &sqlgraph.NodeSpec{
@@ -684,6 +693,12 @@ func (au *AlertUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: alert.FieldCreatedAt,
 		})
 	}
+	if au.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: alert.FieldCreatedAt,
+		})
+	}
 	if value, ok := au.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -691,6 +706,12 @@ func (au *AlertUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: alert.FieldUpdatedAt,
 		})
 	}
+	if au.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: alert.FieldUpdatedAt,
+		})
+	}
 	if value, ok := au.mutation.Scenario(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeString,
@@ -1189,11 +1210,9 @@ func (auo *AlertUpdateOne) SetCreatedAt(t time.Time) *AlertUpdateOne {
 	return auo
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (auo *AlertUpdateOne) SetNillableCreatedAt(t *time.Time) *AlertUpdateOne {
-	if t != nil {
-		auo.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (auo *AlertUpdateOne) ClearCreatedAt() *AlertUpdateOne {
+	auo.mutation.ClearCreatedAt()
 	return auo
 }
 
@@ -1203,11 +1222,9 @@ func (auo *AlertUpdateOne) SetUpdatedAt(t time.Time) *AlertUpdateOne {
 	return auo
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (auo *AlertUpdateOne) SetNillableUpdatedAt(t *time.Time) *AlertUpdateOne {
-	if t != nil {
-		auo.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (auo *AlertUpdateOne) ClearUpdatedAt() *AlertUpdateOne {
+	auo.mutation.ClearUpdatedAt()
 	return auo
 }
 
@@ -1770,6 +1787,7 @@ func (auo *AlertUpdateOne) Save(ctx context.Context) (*Alert, error) {
 		err  error
 		node *Alert
 	)
+	auo.defaults()
 	if len(auo.hooks) == 0 {
 		node, err = auo.sqlSave(ctx)
 	} else {
@@ -1818,6 +1836,18 @@ func (auo *AlertUpdateOne) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (auo *AlertUpdateOne) defaults() {
+	if _, ok := auo.mutation.CreatedAt(); !ok && !auo.mutation.CreatedAtCleared() {
+		v := alert.UpdateDefaultCreatedAt()
+		auo.mutation.SetCreatedAt(v)
+	}
+	if _, ok := auo.mutation.UpdatedAt(); !ok && !auo.mutation.UpdatedAtCleared() {
+		v := alert.UpdateDefaultUpdatedAt()
+		auo.mutation.SetUpdatedAt(v)
+	}
+}
+
 func (auo *AlertUpdateOne) sqlSave(ctx context.Context) (_node *Alert, err error) {
 	_spec := &sqlgraph.UpdateSpec{
 		Node: &sqlgraph.NodeSpec{
@@ -1860,6 +1890,12 @@ func (auo *AlertUpdateOne) sqlSave(ctx context.Context) (_node *Alert, err error
 			Column: alert.FieldCreatedAt,
 		})
 	}
+	if auo.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: alert.FieldCreatedAt,
+		})
+	}
 	if value, ok := auo.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -1867,6 +1903,12 @@ func (auo *AlertUpdateOne) sqlSave(ctx context.Context) (_node *Alert, err error
 			Column: alert.FieldUpdatedAt,
 		})
 	}
+	if auo.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: alert.FieldUpdatedAt,
+		})
+	}
 	if value, ok := auo.mutation.Scenario(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeString,

+ 14 - 8
pkg/database/ent/bouncer.go

@@ -17,9 +17,9 @@ type Bouncer struct {
 	// ID of the ent.
 	ID int `json:"id,omitempty"`
 	// CreatedAt holds the value of the "created_at" field.
-	CreatedAt time.Time `json:"created_at,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
 	// UpdatedAt holds the value of the "updated_at" field.
-	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
 	// Name holds the value of the "name" field.
 	Name string `json:"name,omitempty"`
 	// APIKey holds the value of the "api_key" field.
@@ -76,13 +76,15 @@ func (b *Bouncer) assignValues(columns []string, values []interface{}) error {
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field created_at", values[i])
 			} else if value.Valid {
-				b.CreatedAt = value.Time
+				b.CreatedAt = new(time.Time)
+				*b.CreatedAt = value.Time
 			}
 		case bouncer.FieldUpdatedAt:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
 			} else if value.Valid {
-				b.UpdatedAt = value.Time
+				b.UpdatedAt = new(time.Time)
+				*b.UpdatedAt = value.Time
 			}
 		case bouncer.FieldName:
 			if value, ok := values[i].(*sql.NullString); !ok {
@@ -160,10 +162,14 @@ func (b *Bouncer) String() string {
 	var builder strings.Builder
 	builder.WriteString("Bouncer(")
 	builder.WriteString(fmt.Sprintf("id=%v", b.ID))
-	builder.WriteString(", created_at=")
-	builder.WriteString(b.CreatedAt.Format(time.ANSIC))
-	builder.WriteString(", updated_at=")
-	builder.WriteString(b.UpdatedAt.Format(time.ANSIC))
+	if v := b.CreatedAt; v != nil {
+		builder.WriteString(", created_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := b.UpdatedAt; v != nil {
+		builder.WriteString(", updated_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
 	builder.WriteString(", name=")
 	builder.WriteString(b.Name)
 	builder.WriteString(", api_key=")

+ 4 - 0
pkg/database/ent/bouncer/bouncer.go

@@ -63,8 +63,12 @@ func ValidColumn(column string) bool {
 var (
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
+	// UpdateDefaultCreatedAt holds the default value on update for the "created_at" field.
+	UpdateDefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
 	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultIPAddress holds the default value on creation for the "ip_address" field.
 	DefaultIPAddress string
 	// DefaultUntil holds the default value on creation for the "until" field.

+ 28 - 0
pkg/database/ent/bouncer/where.go

@@ -238,6 +238,20 @@ func CreatedAtLTE(v time.Time) predicate.Bouncer {
 	})
 }
 
+// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
+func CreatedAtIsNil() predicate.Bouncer {
+	return predicate.Bouncer(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldCreatedAt)))
+	})
+}
+
+// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
+func CreatedAtNotNil() predicate.Bouncer {
+	return predicate.Bouncer(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldCreatedAt)))
+	})
+}
+
 // UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
 func UpdatedAtEQ(v time.Time) predicate.Bouncer {
 	return predicate.Bouncer(func(s *sql.Selector) {
@@ -314,6 +328,20 @@ func UpdatedAtLTE(v time.Time) predicate.Bouncer {
 	})
 }
 
+// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
+func UpdatedAtIsNil() predicate.Bouncer {
+	return predicate.Bouncer(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldUpdatedAt)))
+	})
+}
+
+// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
+func UpdatedAtNotNil() predicate.Bouncer {
+	return predicate.Bouncer(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldUpdatedAt)))
+	})
+}
+
 // NameEQ applies the EQ predicate on the "name" field.
 func NameEQ(v string) predicate.Bouncer {
 	return predicate.Bouncer(func(s *sql.Selector) {

+ 2 - 8
pkg/database/ent/bouncer_create.go

@@ -231,12 +231,6 @@ func (bc *BouncerCreate) defaults() {
 
 // check runs all checks and user-defined validators on the builder.
 func (bc *BouncerCreate) check() error {
-	if _, ok := bc.mutation.CreatedAt(); !ok {
-		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)}
-	}
-	if _, ok := bc.mutation.UpdatedAt(); !ok {
-		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)}
-	}
 	if _, ok := bc.mutation.Name(); !ok {
 		return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "name"`)}
 	}
@@ -282,7 +276,7 @@ func (bc *BouncerCreate) createSpec() (*Bouncer, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: bouncer.FieldCreatedAt,
 		})
-		_node.CreatedAt = value
+		_node.CreatedAt = &value
 	}
 	if value, ok := bc.mutation.UpdatedAt(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -290,7 +284,7 @@ func (bc *BouncerCreate) createSpec() (*Bouncer, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: bouncer.FieldUpdatedAt,
 		})
-		_node.UpdatedAt = value
+		_node.UpdatedAt = &value
 	}
 	if value, ok := bc.mutation.Name(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{

+ 62 - 20
pkg/database/ent/bouncer_update.go

@@ -33,11 +33,9 @@ func (bu *BouncerUpdate) SetCreatedAt(t time.Time) *BouncerUpdate {
 	return bu
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (bu *BouncerUpdate) SetNillableCreatedAt(t *time.Time) *BouncerUpdate {
-	if t != nil {
-		bu.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (bu *BouncerUpdate) ClearCreatedAt() *BouncerUpdate {
+	bu.mutation.ClearCreatedAt()
 	return bu
 }
 
@@ -47,11 +45,9 @@ func (bu *BouncerUpdate) SetUpdatedAt(t time.Time) *BouncerUpdate {
 	return bu
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (bu *BouncerUpdate) SetNillableUpdatedAt(t *time.Time) *BouncerUpdate {
-	if t != nil {
-		bu.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (bu *BouncerUpdate) ClearUpdatedAt() *BouncerUpdate {
+	bu.mutation.ClearUpdatedAt()
 	return bu
 }
 
@@ -178,6 +174,7 @@ func (bu *BouncerUpdate) Save(ctx context.Context) (int, error) {
 		err      error
 		affected int
 	)
+	bu.defaults()
 	if len(bu.hooks) == 0 {
 		affected, err = bu.sqlSave(ctx)
 	} else {
@@ -226,6 +223,18 @@ func (bu *BouncerUpdate) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (bu *BouncerUpdate) defaults() {
+	if _, ok := bu.mutation.CreatedAt(); !ok && !bu.mutation.CreatedAtCleared() {
+		v := bouncer.UpdateDefaultCreatedAt()
+		bu.mutation.SetCreatedAt(v)
+	}
+	if _, ok := bu.mutation.UpdatedAt(); !ok && !bu.mutation.UpdatedAtCleared() {
+		v := bouncer.UpdateDefaultUpdatedAt()
+		bu.mutation.SetUpdatedAt(v)
+	}
+}
+
 func (bu *BouncerUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	_spec := &sqlgraph.UpdateSpec{
 		Node: &sqlgraph.NodeSpec{
@@ -251,6 +260,12 @@ func (bu *BouncerUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: bouncer.FieldCreatedAt,
 		})
 	}
+	if bu.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: bouncer.FieldCreatedAt,
+		})
+	}
 	if value, ok := bu.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -258,6 +273,12 @@ func (bu *BouncerUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: bouncer.FieldUpdatedAt,
 		})
 	}
+	if bu.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: bouncer.FieldUpdatedAt,
+		})
+	}
 	if value, ok := bu.mutation.Name(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeString,
@@ -363,11 +384,9 @@ func (buo *BouncerUpdateOne) SetCreatedAt(t time.Time) *BouncerUpdateOne {
 	return buo
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (buo *BouncerUpdateOne) SetNillableCreatedAt(t *time.Time) *BouncerUpdateOne {
-	if t != nil {
-		buo.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (buo *BouncerUpdateOne) ClearCreatedAt() *BouncerUpdateOne {
+	buo.mutation.ClearCreatedAt()
 	return buo
 }
 
@@ -377,11 +396,9 @@ func (buo *BouncerUpdateOne) SetUpdatedAt(t time.Time) *BouncerUpdateOne {
 	return buo
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (buo *BouncerUpdateOne) SetNillableUpdatedAt(t *time.Time) *BouncerUpdateOne {
-	if t != nil {
-		buo.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (buo *BouncerUpdateOne) ClearUpdatedAt() *BouncerUpdateOne {
+	buo.mutation.ClearUpdatedAt()
 	return buo
 }
 
@@ -515,6 +532,7 @@ func (buo *BouncerUpdateOne) Save(ctx context.Context) (*Bouncer, error) {
 		err  error
 		node *Bouncer
 	)
+	buo.defaults()
 	if len(buo.hooks) == 0 {
 		node, err = buo.sqlSave(ctx)
 	} else {
@@ -563,6 +581,18 @@ func (buo *BouncerUpdateOne) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (buo *BouncerUpdateOne) defaults() {
+	if _, ok := buo.mutation.CreatedAt(); !ok && !buo.mutation.CreatedAtCleared() {
+		v := bouncer.UpdateDefaultCreatedAt()
+		buo.mutation.SetCreatedAt(v)
+	}
+	if _, ok := buo.mutation.UpdatedAt(); !ok && !buo.mutation.UpdatedAtCleared() {
+		v := bouncer.UpdateDefaultUpdatedAt()
+		buo.mutation.SetUpdatedAt(v)
+	}
+}
+
 func (buo *BouncerUpdateOne) sqlSave(ctx context.Context) (_node *Bouncer, err error) {
 	_spec := &sqlgraph.UpdateSpec{
 		Node: &sqlgraph.NodeSpec{
@@ -605,6 +635,12 @@ func (buo *BouncerUpdateOne) sqlSave(ctx context.Context) (_node *Bouncer, err e
 			Column: bouncer.FieldCreatedAt,
 		})
 	}
+	if buo.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: bouncer.FieldCreatedAt,
+		})
+	}
 	if value, ok := buo.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -612,6 +648,12 @@ func (buo *BouncerUpdateOne) sqlSave(ctx context.Context) (_node *Bouncer, err e
 			Column: bouncer.FieldUpdatedAt,
 		})
 	}
+	if buo.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: bouncer.FieldUpdatedAt,
+		})
+	}
 	if value, ok := buo.mutation.Name(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeString,

+ 14 - 8
pkg/database/ent/decision.go

@@ -18,9 +18,9 @@ type Decision struct {
 	// ID of the ent.
 	ID int `json:"id,omitempty"`
 	// CreatedAt holds the value of the "created_at" field.
-	CreatedAt time.Time `json:"created_at,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
 	// UpdatedAt holds the value of the "updated_at" field.
-	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
 	// Until holds the value of the "until" field.
 	Until time.Time `json:"until,omitempty"`
 	// Scenario holds the value of the "scenario" field.
@@ -114,13 +114,15 @@ func (d *Decision) assignValues(columns []string, values []interface{}) error {
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field created_at", values[i])
 			} else if value.Valid {
-				d.CreatedAt = value.Time
+				d.CreatedAt = new(time.Time)
+				*d.CreatedAt = value.Time
 			}
 		case decision.FieldUpdatedAt:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
 			} else if value.Valid {
-				d.UpdatedAt = value.Time
+				d.UpdatedAt = new(time.Time)
+				*d.UpdatedAt = value.Time
 			}
 		case decision.FieldUntil:
 			if value, ok := values[i].(*sql.NullTime); !ok {
@@ -234,10 +236,14 @@ func (d *Decision) String() string {
 	var builder strings.Builder
 	builder.WriteString("Decision(")
 	builder.WriteString(fmt.Sprintf("id=%v", d.ID))
-	builder.WriteString(", created_at=")
-	builder.WriteString(d.CreatedAt.Format(time.ANSIC))
-	builder.WriteString(", updated_at=")
-	builder.WriteString(d.UpdatedAt.Format(time.ANSIC))
+	if v := d.CreatedAt; v != nil {
+		builder.WriteString(", created_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := d.UpdatedAt; v != nil {
+		builder.WriteString(", updated_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
 	builder.WriteString(", until=")
 	builder.WriteString(d.Until.Format(time.ANSIC))
 	builder.WriteString(", scenario=")

+ 4 - 0
pkg/database/ent/decision/decision.go

@@ -95,8 +95,12 @@ func ValidColumn(column string) bool {
 var (
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
+	// UpdateDefaultCreatedAt holds the default value on update for the "created_at" field.
+	UpdateDefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
 	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultSimulated holds the default value on creation for the "simulated" field.
 	DefaultSimulated bool
 )

+ 28 - 0
pkg/database/ent/decision/where.go

@@ -267,6 +267,20 @@ func CreatedAtLTE(v time.Time) predicate.Decision {
 	})
 }
 
+// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
+func CreatedAtIsNil() predicate.Decision {
+	return predicate.Decision(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldCreatedAt)))
+	})
+}
+
+// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
+func CreatedAtNotNil() predicate.Decision {
+	return predicate.Decision(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldCreatedAt)))
+	})
+}
+
 // UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
 func UpdatedAtEQ(v time.Time) predicate.Decision {
 	return predicate.Decision(func(s *sql.Selector) {
@@ -343,6 +357,20 @@ func UpdatedAtLTE(v time.Time) predicate.Decision {
 	})
 }
 
+// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
+func UpdatedAtIsNil() predicate.Decision {
+	return predicate.Decision(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldUpdatedAt)))
+	})
+}
+
+// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
+func UpdatedAtNotNil() predicate.Decision {
+	return predicate.Decision(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldUpdatedAt)))
+	})
+}
+
 // UntilEQ applies the EQ predicate on the "until" field.
 func UntilEQ(v time.Time) predicate.Decision {
 	return predicate.Decision(func(s *sql.Selector) {

+ 2 - 8
pkg/database/ent/decision_create.go

@@ -275,12 +275,6 @@ func (dc *DecisionCreate) defaults() {
 
 // check runs all checks and user-defined validators on the builder.
 func (dc *DecisionCreate) check() error {
-	if _, ok := dc.mutation.CreatedAt(); !ok {
-		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)}
-	}
-	if _, ok := dc.mutation.UpdatedAt(); !ok {
-		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)}
-	}
 	if _, ok := dc.mutation.Until(); !ok {
 		return &ValidationError{Name: "until", err: errors.New(`ent: missing required field "until"`)}
 	}
@@ -335,7 +329,7 @@ func (dc *DecisionCreate) createSpec() (*Decision, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: decision.FieldCreatedAt,
 		})
-		_node.CreatedAt = value
+		_node.CreatedAt = &value
 	}
 	if value, ok := dc.mutation.UpdatedAt(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -343,7 +337,7 @@ func (dc *DecisionCreate) createSpec() (*Decision, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: decision.FieldUpdatedAt,
 		})
-		_node.UpdatedAt = value
+		_node.UpdatedAt = &value
 	}
 	if value, ok := dc.mutation.Until(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{

+ 62 - 20
pkg/database/ent/decision_update.go

@@ -34,11 +34,9 @@ func (du *DecisionUpdate) SetCreatedAt(t time.Time) *DecisionUpdate {
 	return du
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (du *DecisionUpdate) SetNillableCreatedAt(t *time.Time) *DecisionUpdate {
-	if t != nil {
-		du.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (du *DecisionUpdate) ClearCreatedAt() *DecisionUpdate {
+	du.mutation.ClearCreatedAt()
 	return du
 }
 
@@ -48,11 +46,9 @@ func (du *DecisionUpdate) SetUpdatedAt(t time.Time) *DecisionUpdate {
 	return du
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (du *DecisionUpdate) SetNillableUpdatedAt(t *time.Time) *DecisionUpdate {
-	if t != nil {
-		du.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (du *DecisionUpdate) ClearUpdatedAt() *DecisionUpdate {
+	du.mutation.ClearUpdatedAt()
 	return du
 }
 
@@ -277,6 +273,7 @@ func (du *DecisionUpdate) Save(ctx context.Context) (int, error) {
 		err      error
 		affected int
 	)
+	du.defaults()
 	if len(du.hooks) == 0 {
 		affected, err = du.sqlSave(ctx)
 	} else {
@@ -325,6 +322,18 @@ func (du *DecisionUpdate) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (du *DecisionUpdate) defaults() {
+	if _, ok := du.mutation.CreatedAt(); !ok && !du.mutation.CreatedAtCleared() {
+		v := decision.UpdateDefaultCreatedAt()
+		du.mutation.SetCreatedAt(v)
+	}
+	if _, ok := du.mutation.UpdatedAt(); !ok && !du.mutation.UpdatedAtCleared() {
+		v := decision.UpdateDefaultUpdatedAt()
+		du.mutation.SetUpdatedAt(v)
+	}
+}
+
 func (du *DecisionUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	_spec := &sqlgraph.UpdateSpec{
 		Node: &sqlgraph.NodeSpec{
@@ -350,6 +359,12 @@ func (du *DecisionUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: decision.FieldCreatedAt,
 		})
 	}
+	if du.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: decision.FieldCreatedAt,
+		})
+	}
 	if value, ok := du.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -357,6 +372,12 @@ func (du *DecisionUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: decision.FieldUpdatedAt,
 		})
 	}
+	if du.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: decision.FieldUpdatedAt,
+		})
+	}
 	if value, ok := du.mutation.Until(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -566,11 +587,9 @@ func (duo *DecisionUpdateOne) SetCreatedAt(t time.Time) *DecisionUpdateOne {
 	return duo
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (duo *DecisionUpdateOne) SetNillableCreatedAt(t *time.Time) *DecisionUpdateOne {
-	if t != nil {
-		duo.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (duo *DecisionUpdateOne) ClearCreatedAt() *DecisionUpdateOne {
+	duo.mutation.ClearCreatedAt()
 	return duo
 }
 
@@ -580,11 +599,9 @@ func (duo *DecisionUpdateOne) SetUpdatedAt(t time.Time) *DecisionUpdateOne {
 	return duo
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (duo *DecisionUpdateOne) SetNillableUpdatedAt(t *time.Time) *DecisionUpdateOne {
-	if t != nil {
-		duo.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (duo *DecisionUpdateOne) ClearUpdatedAt() *DecisionUpdateOne {
+	duo.mutation.ClearUpdatedAt()
 	return duo
 }
 
@@ -816,6 +833,7 @@ func (duo *DecisionUpdateOne) Save(ctx context.Context) (*Decision, error) {
 		err  error
 		node *Decision
 	)
+	duo.defaults()
 	if len(duo.hooks) == 0 {
 		node, err = duo.sqlSave(ctx)
 	} else {
@@ -864,6 +882,18 @@ func (duo *DecisionUpdateOne) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (duo *DecisionUpdateOne) defaults() {
+	if _, ok := duo.mutation.CreatedAt(); !ok && !duo.mutation.CreatedAtCleared() {
+		v := decision.UpdateDefaultCreatedAt()
+		duo.mutation.SetCreatedAt(v)
+	}
+	if _, ok := duo.mutation.UpdatedAt(); !ok && !duo.mutation.UpdatedAtCleared() {
+		v := decision.UpdateDefaultUpdatedAt()
+		duo.mutation.SetUpdatedAt(v)
+	}
+}
+
 func (duo *DecisionUpdateOne) sqlSave(ctx context.Context) (_node *Decision, err error) {
 	_spec := &sqlgraph.UpdateSpec{
 		Node: &sqlgraph.NodeSpec{
@@ -906,6 +936,12 @@ func (duo *DecisionUpdateOne) sqlSave(ctx context.Context) (_node *Decision, err
 			Column: decision.FieldCreatedAt,
 		})
 	}
+	if duo.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: decision.FieldCreatedAt,
+		})
+	}
 	if value, ok := duo.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -913,6 +949,12 @@ func (duo *DecisionUpdateOne) sqlSave(ctx context.Context) (_node *Decision, err
 			Column: decision.FieldUpdatedAt,
 		})
 	}
+	if duo.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: decision.FieldUpdatedAt,
+		})
+	}
 	if value, ok := duo.mutation.Until(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,

+ 14 - 8
pkg/database/ent/event.go

@@ -18,9 +18,9 @@ type Event struct {
 	// ID of the ent.
 	ID int `json:"id,omitempty"`
 	// CreatedAt holds the value of the "created_at" field.
-	CreatedAt time.Time `json:"created_at,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
 	// UpdatedAt holds the value of the "updated_at" field.
-	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
 	// Time holds the value of the "time" field.
 	Time time.Time `json:"time,omitempty"`
 	// Serialized holds the value of the "serialized" field.
@@ -92,13 +92,15 @@ func (e *Event) assignValues(columns []string, values []interface{}) error {
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field created_at", values[i])
 			} else if value.Valid {
-				e.CreatedAt = value.Time
+				e.CreatedAt = new(time.Time)
+				*e.CreatedAt = value.Time
 			}
 		case event.FieldUpdatedAt:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
 			} else if value.Valid {
-				e.UpdatedAt = value.Time
+				e.UpdatedAt = new(time.Time)
+				*e.UpdatedAt = value.Time
 			}
 		case event.FieldTime:
 			if value, ok := values[i].(*sql.NullTime); !ok {
@@ -152,10 +154,14 @@ func (e *Event) String() string {
 	var builder strings.Builder
 	builder.WriteString("Event(")
 	builder.WriteString(fmt.Sprintf("id=%v", e.ID))
-	builder.WriteString(", created_at=")
-	builder.WriteString(e.CreatedAt.Format(time.ANSIC))
-	builder.WriteString(", updated_at=")
-	builder.WriteString(e.UpdatedAt.Format(time.ANSIC))
+	if v := e.CreatedAt; v != nil {
+		builder.WriteString(", created_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := e.UpdatedAt; v != nil {
+		builder.WriteString(", updated_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
 	builder.WriteString(", time=")
 	builder.WriteString(e.Time.Format(time.ANSIC))
 	builder.WriteString(", serialized=")

+ 4 - 0
pkg/database/ent/event/event.go

@@ -65,8 +65,12 @@ func ValidColumn(column string) bool {
 var (
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
+	// UpdateDefaultCreatedAt holds the default value on update for the "created_at" field.
+	UpdateDefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
 	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
 	// SerializedValidator is a validator for the "serialized" field. It is called by the builders before save.
 	SerializedValidator func(string) error
 )

+ 28 - 0
pkg/database/ent/event/where.go

@@ -197,6 +197,20 @@ func CreatedAtLTE(v time.Time) predicate.Event {
 	})
 }
 
+// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
+func CreatedAtIsNil() predicate.Event {
+	return predicate.Event(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldCreatedAt)))
+	})
+}
+
+// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
+func CreatedAtNotNil() predicate.Event {
+	return predicate.Event(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldCreatedAt)))
+	})
+}
+
 // UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
 func UpdatedAtEQ(v time.Time) predicate.Event {
 	return predicate.Event(func(s *sql.Selector) {
@@ -273,6 +287,20 @@ func UpdatedAtLTE(v time.Time) predicate.Event {
 	})
 }
 
+// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
+func UpdatedAtIsNil() predicate.Event {
+	return predicate.Event(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldUpdatedAt)))
+	})
+}
+
+// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
+func UpdatedAtNotNil() predicate.Event {
+	return predicate.Event(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldUpdatedAt)))
+	})
+}
+
 // TimeEQ applies the EQ predicate on the "time" field.
 func TimeEQ(v time.Time) predicate.Event {
 	return predicate.Event(func(s *sql.Selector) {

+ 2 - 8
pkg/database/ent/event_create.go

@@ -163,12 +163,6 @@ func (ec *EventCreate) defaults() {
 
 // check runs all checks and user-defined validators on the builder.
 func (ec *EventCreate) check() error {
-	if _, ok := ec.mutation.CreatedAt(); !ok {
-		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)}
-	}
-	if _, ok := ec.mutation.UpdatedAt(); !ok {
-		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)}
-	}
 	if _, ok := ec.mutation.Time(); !ok {
 		return &ValidationError{Name: "time", err: errors.New(`ent: missing required field "time"`)}
 	}
@@ -213,7 +207,7 @@ func (ec *EventCreate) createSpec() (*Event, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: event.FieldCreatedAt,
 		})
-		_node.CreatedAt = value
+		_node.CreatedAt = &value
 	}
 	if value, ok := ec.mutation.UpdatedAt(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -221,7 +215,7 @@ func (ec *EventCreate) createSpec() (*Event, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: event.FieldUpdatedAt,
 		})
-		_node.UpdatedAt = value
+		_node.UpdatedAt = &value
 	}
 	if value, ok := ec.mutation.Time(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{

+ 62 - 20
pkg/database/ent/event_update.go

@@ -34,11 +34,9 @@ func (eu *EventUpdate) SetCreatedAt(t time.Time) *EventUpdate {
 	return eu
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (eu *EventUpdate) SetNillableCreatedAt(t *time.Time) *EventUpdate {
-	if t != nil {
-		eu.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (eu *EventUpdate) ClearCreatedAt() *EventUpdate {
+	eu.mutation.ClearCreatedAt()
 	return eu
 }
 
@@ -48,11 +46,9 @@ func (eu *EventUpdate) SetUpdatedAt(t time.Time) *EventUpdate {
 	return eu
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (eu *EventUpdate) SetNillableUpdatedAt(t *time.Time) *EventUpdate {
-	if t != nil {
-		eu.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (eu *EventUpdate) ClearUpdatedAt() *EventUpdate {
+	eu.mutation.ClearUpdatedAt()
 	return eu
 }
 
@@ -104,6 +100,7 @@ func (eu *EventUpdate) Save(ctx context.Context) (int, error) {
 		err      error
 		affected int
 	)
+	eu.defaults()
 	if len(eu.hooks) == 0 {
 		if err = eu.check(); err != nil {
 			return 0, err
@@ -158,6 +155,18 @@ func (eu *EventUpdate) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (eu *EventUpdate) defaults() {
+	if _, ok := eu.mutation.CreatedAt(); !ok && !eu.mutation.CreatedAtCleared() {
+		v := event.UpdateDefaultCreatedAt()
+		eu.mutation.SetCreatedAt(v)
+	}
+	if _, ok := eu.mutation.UpdatedAt(); !ok && !eu.mutation.UpdatedAtCleared() {
+		v := event.UpdateDefaultUpdatedAt()
+		eu.mutation.SetUpdatedAt(v)
+	}
+}
+
 // check runs all checks and user-defined validators on the builder.
 func (eu *EventUpdate) check() error {
 	if v, ok := eu.mutation.Serialized(); ok {
@@ -193,6 +202,12 @@ func (eu *EventUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: event.FieldCreatedAt,
 		})
 	}
+	if eu.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: event.FieldCreatedAt,
+		})
+	}
 	if value, ok := eu.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -200,6 +215,12 @@ func (eu *EventUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: event.FieldUpdatedAt,
 		})
 	}
+	if eu.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: event.FieldUpdatedAt,
+		})
+	}
 	if value, ok := eu.mutation.Time(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -274,11 +295,9 @@ func (euo *EventUpdateOne) SetCreatedAt(t time.Time) *EventUpdateOne {
 	return euo
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (euo *EventUpdateOne) SetNillableCreatedAt(t *time.Time) *EventUpdateOne {
-	if t != nil {
-		euo.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (euo *EventUpdateOne) ClearCreatedAt() *EventUpdateOne {
+	euo.mutation.ClearCreatedAt()
 	return euo
 }
 
@@ -288,11 +307,9 @@ func (euo *EventUpdateOne) SetUpdatedAt(t time.Time) *EventUpdateOne {
 	return euo
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (euo *EventUpdateOne) SetNillableUpdatedAt(t *time.Time) *EventUpdateOne {
-	if t != nil {
-		euo.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (euo *EventUpdateOne) ClearUpdatedAt() *EventUpdateOne {
+	euo.mutation.ClearUpdatedAt()
 	return euo
 }
 
@@ -351,6 +368,7 @@ func (euo *EventUpdateOne) Save(ctx context.Context) (*Event, error) {
 		err  error
 		node *Event
 	)
+	euo.defaults()
 	if len(euo.hooks) == 0 {
 		if err = euo.check(); err != nil {
 			return nil, err
@@ -405,6 +423,18 @@ func (euo *EventUpdateOne) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (euo *EventUpdateOne) defaults() {
+	if _, ok := euo.mutation.CreatedAt(); !ok && !euo.mutation.CreatedAtCleared() {
+		v := event.UpdateDefaultCreatedAt()
+		euo.mutation.SetCreatedAt(v)
+	}
+	if _, ok := euo.mutation.UpdatedAt(); !ok && !euo.mutation.UpdatedAtCleared() {
+		v := event.UpdateDefaultUpdatedAt()
+		euo.mutation.SetUpdatedAt(v)
+	}
+}
+
 // check runs all checks and user-defined validators on the builder.
 func (euo *EventUpdateOne) check() error {
 	if v, ok := euo.mutation.Serialized(); ok {
@@ -457,6 +487,12 @@ func (euo *EventUpdateOne) sqlSave(ctx context.Context) (_node *Event, err error
 			Column: event.FieldCreatedAt,
 		})
 	}
+	if euo.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: event.FieldCreatedAt,
+		})
+	}
 	if value, ok := euo.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -464,6 +500,12 @@ func (euo *EventUpdateOne) sqlSave(ctx context.Context) (_node *Event, err error
 			Column: event.FieldUpdatedAt,
 		})
 	}
+	if euo.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: event.FieldUpdatedAt,
+		})
+	}
 	if value, ok := euo.mutation.Time(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,

+ 21 - 12
pkg/database/ent/machine.go

@@ -17,11 +17,11 @@ type Machine struct {
 	// ID of the ent.
 	ID int `json:"id,omitempty"`
 	// CreatedAt holds the value of the "created_at" field.
-	CreatedAt time.Time `json:"created_at,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
 	// UpdatedAt holds the value of the "updated_at" field.
-	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
 	// LastPush holds the value of the "last_push" field.
-	LastPush time.Time `json:"last_push,omitempty"`
+	LastPush *time.Time `json:"last_push,omitempty"`
 	// MachineId holds the value of the "machineId" field.
 	MachineId string `json:"machineId,omitempty"`
 	// Password holds the value of the "password" field.
@@ -97,19 +97,22 @@ func (m *Machine) assignValues(columns []string, values []interface{}) error {
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field created_at", values[i])
 			} else if value.Valid {
-				m.CreatedAt = value.Time
+				m.CreatedAt = new(time.Time)
+				*m.CreatedAt = value.Time
 			}
 		case machine.FieldUpdatedAt:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
 			} else if value.Valid {
-				m.UpdatedAt = value.Time
+				m.UpdatedAt = new(time.Time)
+				*m.UpdatedAt = value.Time
 			}
 		case machine.FieldLastPush:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field last_push", values[i])
 			} else if value.Valid {
-				m.LastPush = value.Time
+				m.LastPush = new(time.Time)
+				*m.LastPush = value.Time
 			}
 		case machine.FieldMachineId:
 			if value, ok := values[i].(*sql.NullString); !ok {
@@ -186,12 +189,18 @@ func (m *Machine) String() string {
 	var builder strings.Builder
 	builder.WriteString("Machine(")
 	builder.WriteString(fmt.Sprintf("id=%v", m.ID))
-	builder.WriteString(", created_at=")
-	builder.WriteString(m.CreatedAt.Format(time.ANSIC))
-	builder.WriteString(", updated_at=")
-	builder.WriteString(m.UpdatedAt.Format(time.ANSIC))
-	builder.WriteString(", last_push=")
-	builder.WriteString(m.LastPush.Format(time.ANSIC))
+	if v := m.CreatedAt; v != nil {
+		builder.WriteString(", created_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := m.UpdatedAt; v != nil {
+		builder.WriteString(", updated_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := m.LastPush; v != nil {
+		builder.WriteString(", last_push=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
 	builder.WriteString(", machineId=")
 	builder.WriteString(m.MachineId)
 	builder.WriteString(", password=<sensitive>")

+ 6 - 0
pkg/database/ent/machine/machine.go

@@ -72,10 +72,16 @@ func ValidColumn(column string) bool {
 var (
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
+	// UpdateDefaultCreatedAt holds the default value on update for the "created_at" field.
+	UpdateDefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
 	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
 	// DefaultLastPush holds the default value on creation for the "last_push" field.
 	DefaultLastPush func() time.Time
+	// UpdateDefaultLastPush holds the default value on update for the "last_push" field.
+	UpdateDefaultLastPush func() time.Time
 	// ScenariosValidator is a validator for the "scenarios" field. It is called by the builders before save.
 	ScenariosValidator func(string) error
 	// DefaultIsValidated holds the default value on creation for the "isValidated" field.

+ 28 - 0
pkg/database/ent/machine/where.go

@@ -239,6 +239,20 @@ func CreatedAtLTE(v time.Time) predicate.Machine {
 	})
 }
 
+// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
+func CreatedAtIsNil() predicate.Machine {
+	return predicate.Machine(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldCreatedAt)))
+	})
+}
+
+// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
+func CreatedAtNotNil() predicate.Machine {
+	return predicate.Machine(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldCreatedAt)))
+	})
+}
+
 // UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
 func UpdatedAtEQ(v time.Time) predicate.Machine {
 	return predicate.Machine(func(s *sql.Selector) {
@@ -315,6 +329,20 @@ func UpdatedAtLTE(v time.Time) predicate.Machine {
 	})
 }
 
+// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
+func UpdatedAtIsNil() predicate.Machine {
+	return predicate.Machine(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldUpdatedAt)))
+	})
+}
+
+// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
+func UpdatedAtNotNil() predicate.Machine {
+	return predicate.Machine(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldUpdatedAt)))
+	})
+}
+
 // LastPushEQ applies the EQ predicate on the "last_push" field.
 func LastPushEQ(v time.Time) predicate.Machine {
 	return predicate.Machine(func(s *sql.Selector) {

+ 3 - 9
pkg/database/ent/machine_create.go

@@ -243,12 +243,6 @@ func (mc *MachineCreate) defaults() {
 
 // check runs all checks and user-defined validators on the builder.
 func (mc *MachineCreate) check() error {
-	if _, ok := mc.mutation.CreatedAt(); !ok {
-		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)}
-	}
-	if _, ok := mc.mutation.UpdatedAt(); !ok {
-		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)}
-	}
 	if _, ok := mc.mutation.MachineId(); !ok {
 		return &ValidationError{Name: "machineId", err: errors.New(`ent: missing required field "machineId"`)}
 	}
@@ -299,7 +293,7 @@ func (mc *MachineCreate) createSpec() (*Machine, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: machine.FieldCreatedAt,
 		})
-		_node.CreatedAt = value
+		_node.CreatedAt = &value
 	}
 	if value, ok := mc.mutation.UpdatedAt(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -307,7 +301,7 @@ func (mc *MachineCreate) createSpec() (*Machine, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: machine.FieldUpdatedAt,
 		})
-		_node.UpdatedAt = value
+		_node.UpdatedAt = &value
 	}
 	if value, ok := mc.mutation.LastPush(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -315,7 +309,7 @@ func (mc *MachineCreate) createSpec() (*Machine, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: machine.FieldLastPush,
 		})
-		_node.LastPush = value
+		_node.LastPush = &value
 	}
 	if value, ok := mc.mutation.MachineId(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{

+ 70 - 36
pkg/database/ent/machine_update.go

@@ -34,11 +34,9 @@ func (mu *MachineUpdate) SetCreatedAt(t time.Time) *MachineUpdate {
 	return mu
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (mu *MachineUpdate) SetNillableCreatedAt(t *time.Time) *MachineUpdate {
-	if t != nil {
-		mu.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (mu *MachineUpdate) ClearCreatedAt() *MachineUpdate {
+	mu.mutation.ClearCreatedAt()
 	return mu
 }
 
@@ -48,11 +46,9 @@ func (mu *MachineUpdate) SetUpdatedAt(t time.Time) *MachineUpdate {
 	return mu
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (mu *MachineUpdate) SetNillableUpdatedAt(t *time.Time) *MachineUpdate {
-	if t != nil {
-		mu.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (mu *MachineUpdate) ClearUpdatedAt() *MachineUpdate {
+	mu.mutation.ClearUpdatedAt()
 	return mu
 }
 
@@ -62,14 +58,6 @@ func (mu *MachineUpdate) SetLastPush(t time.Time) *MachineUpdate {
 	return mu
 }
 
-// SetNillableLastPush sets the "last_push" field if the given value is not nil.
-func (mu *MachineUpdate) SetNillableLastPush(t *time.Time) *MachineUpdate {
-	if t != nil {
-		mu.SetLastPush(*t)
-	}
-	return mu
-}
-
 // ClearLastPush clears the value of the "last_push" field.
 func (mu *MachineUpdate) ClearLastPush() *MachineUpdate {
 	mu.mutation.ClearLastPush()
@@ -215,6 +203,7 @@ func (mu *MachineUpdate) Save(ctx context.Context) (int, error) {
 		err      error
 		affected int
 	)
+	mu.defaults()
 	if len(mu.hooks) == 0 {
 		if err = mu.check(); err != nil {
 			return 0, err
@@ -269,6 +258,22 @@ func (mu *MachineUpdate) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (mu *MachineUpdate) defaults() {
+	if _, ok := mu.mutation.CreatedAt(); !ok && !mu.mutation.CreatedAtCleared() {
+		v := machine.UpdateDefaultCreatedAt()
+		mu.mutation.SetCreatedAt(v)
+	}
+	if _, ok := mu.mutation.UpdatedAt(); !ok && !mu.mutation.UpdatedAtCleared() {
+		v := machine.UpdateDefaultUpdatedAt()
+		mu.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := mu.mutation.LastPush(); !ok && !mu.mutation.LastPushCleared() {
+		v := machine.UpdateDefaultLastPush()
+		mu.mutation.SetLastPush(v)
+	}
+}
+
 // check runs all checks and user-defined validators on the builder.
 func (mu *MachineUpdate) check() error {
 	if v, ok := mu.mutation.Scenarios(); ok {
@@ -304,6 +309,12 @@ func (mu *MachineUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: machine.FieldCreatedAt,
 		})
 	}
+	if mu.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: machine.FieldCreatedAt,
+		})
+	}
 	if value, ok := mu.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -311,6 +322,12 @@ func (mu *MachineUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: machine.FieldUpdatedAt,
 		})
 	}
+	if mu.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: machine.FieldUpdatedAt,
+		})
+	}
 	if value, ok := mu.mutation.LastPush(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -470,11 +487,9 @@ func (muo *MachineUpdateOne) SetCreatedAt(t time.Time) *MachineUpdateOne {
 	return muo
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (muo *MachineUpdateOne) SetNillableCreatedAt(t *time.Time) *MachineUpdateOne {
-	if t != nil {
-		muo.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (muo *MachineUpdateOne) ClearCreatedAt() *MachineUpdateOne {
+	muo.mutation.ClearCreatedAt()
 	return muo
 }
 
@@ -484,11 +499,9 @@ func (muo *MachineUpdateOne) SetUpdatedAt(t time.Time) *MachineUpdateOne {
 	return muo
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (muo *MachineUpdateOne) SetNillableUpdatedAt(t *time.Time) *MachineUpdateOne {
-	if t != nil {
-		muo.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (muo *MachineUpdateOne) ClearUpdatedAt() *MachineUpdateOne {
+	muo.mutation.ClearUpdatedAt()
 	return muo
 }
 
@@ -498,14 +511,6 @@ func (muo *MachineUpdateOne) SetLastPush(t time.Time) *MachineUpdateOne {
 	return muo
 }
 
-// SetNillableLastPush sets the "last_push" field if the given value is not nil.
-func (muo *MachineUpdateOne) SetNillableLastPush(t *time.Time) *MachineUpdateOne {
-	if t != nil {
-		muo.SetLastPush(*t)
-	}
-	return muo
-}
-
 // ClearLastPush clears the value of the "last_push" field.
 func (muo *MachineUpdateOne) ClearLastPush() *MachineUpdateOne {
 	muo.mutation.ClearLastPush()
@@ -658,6 +663,7 @@ func (muo *MachineUpdateOne) Save(ctx context.Context) (*Machine, error) {
 		err  error
 		node *Machine
 	)
+	muo.defaults()
 	if len(muo.hooks) == 0 {
 		if err = muo.check(); err != nil {
 			return nil, err
@@ -712,6 +718,22 @@ func (muo *MachineUpdateOne) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (muo *MachineUpdateOne) defaults() {
+	if _, ok := muo.mutation.CreatedAt(); !ok && !muo.mutation.CreatedAtCleared() {
+		v := machine.UpdateDefaultCreatedAt()
+		muo.mutation.SetCreatedAt(v)
+	}
+	if _, ok := muo.mutation.UpdatedAt(); !ok && !muo.mutation.UpdatedAtCleared() {
+		v := machine.UpdateDefaultUpdatedAt()
+		muo.mutation.SetUpdatedAt(v)
+	}
+	if _, ok := muo.mutation.LastPush(); !ok && !muo.mutation.LastPushCleared() {
+		v := machine.UpdateDefaultLastPush()
+		muo.mutation.SetLastPush(v)
+	}
+}
+
 // check runs all checks and user-defined validators on the builder.
 func (muo *MachineUpdateOne) check() error {
 	if v, ok := muo.mutation.Scenarios(); ok {
@@ -764,6 +786,12 @@ func (muo *MachineUpdateOne) sqlSave(ctx context.Context) (_node *Machine, err e
 			Column: machine.FieldCreatedAt,
 		})
 	}
+	if muo.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: machine.FieldCreatedAt,
+		})
+	}
 	if value, ok := muo.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -771,6 +799,12 @@ func (muo *MachineUpdateOne) sqlSave(ctx context.Context) (_node *Machine, err e
 			Column: machine.FieldUpdatedAt,
 		})
 	}
+	if muo.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: machine.FieldUpdatedAt,
+		})
+	}
 	if value, ok := muo.mutation.LastPush(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,

+ 14 - 8
pkg/database/ent/meta.go

@@ -18,9 +18,9 @@ type Meta struct {
 	// ID of the ent.
 	ID int `json:"id,omitempty"`
 	// CreatedAt holds the value of the "created_at" field.
-	CreatedAt time.Time `json:"created_at,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
 	// UpdatedAt holds the value of the "updated_at" field.
-	UpdatedAt time.Time `json:"updated_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
 	// Key holds the value of the "key" field.
 	Key string `json:"key,omitempty"`
 	// Value holds the value of the "value" field.
@@ -92,13 +92,15 @@ func (m *Meta) assignValues(columns []string, values []interface{}) error {
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field created_at", values[i])
 			} else if value.Valid {
-				m.CreatedAt = value.Time
+				m.CreatedAt = new(time.Time)
+				*m.CreatedAt = value.Time
 			}
 		case meta.FieldUpdatedAt:
 			if value, ok := values[i].(*sql.NullTime); !ok {
 				return fmt.Errorf("unexpected type %T for field updated_at", values[i])
 			} else if value.Valid {
-				m.UpdatedAt = value.Time
+				m.UpdatedAt = new(time.Time)
+				*m.UpdatedAt = value.Time
 			}
 		case meta.FieldKey:
 			if value, ok := values[i].(*sql.NullString); !ok {
@@ -152,10 +154,14 @@ func (m *Meta) String() string {
 	var builder strings.Builder
 	builder.WriteString("Meta(")
 	builder.WriteString(fmt.Sprintf("id=%v", m.ID))
-	builder.WriteString(", created_at=")
-	builder.WriteString(m.CreatedAt.Format(time.ANSIC))
-	builder.WriteString(", updated_at=")
-	builder.WriteString(m.UpdatedAt.Format(time.ANSIC))
+	if v := m.CreatedAt; v != nil {
+		builder.WriteString(", created_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
+	if v := m.UpdatedAt; v != nil {
+		builder.WriteString(", updated_at=")
+		builder.WriteString(v.Format(time.ANSIC))
+	}
 	builder.WriteString(", key=")
 	builder.WriteString(m.Key)
 	builder.WriteString(", value=")

+ 4 - 0
pkg/database/ent/meta/meta.go

@@ -65,8 +65,12 @@ func ValidColumn(column string) bool {
 var (
 	// DefaultCreatedAt holds the default value on creation for the "created_at" field.
 	DefaultCreatedAt func() time.Time
+	// UpdateDefaultCreatedAt holds the default value on update for the "created_at" field.
+	UpdateDefaultCreatedAt func() time.Time
 	// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
 	DefaultUpdatedAt func() time.Time
+	// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
+	UpdateDefaultUpdatedAt func() time.Time
 	// ValueValidator is a validator for the "value" field. It is called by the builders before save.
 	ValueValidator func(string) error
 )

+ 28 - 0
pkg/database/ent/meta/where.go

@@ -197,6 +197,20 @@ func CreatedAtLTE(v time.Time) predicate.Meta {
 	})
 }
 
+// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
+func CreatedAtIsNil() predicate.Meta {
+	return predicate.Meta(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldCreatedAt)))
+	})
+}
+
+// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
+func CreatedAtNotNil() predicate.Meta {
+	return predicate.Meta(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldCreatedAt)))
+	})
+}
+
 // UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
 func UpdatedAtEQ(v time.Time) predicate.Meta {
 	return predicate.Meta(func(s *sql.Selector) {
@@ -273,6 +287,20 @@ func UpdatedAtLTE(v time.Time) predicate.Meta {
 	})
 }
 
+// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
+func UpdatedAtIsNil() predicate.Meta {
+	return predicate.Meta(func(s *sql.Selector) {
+		s.Where(sql.IsNull(s.C(FieldUpdatedAt)))
+	})
+}
+
+// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
+func UpdatedAtNotNil() predicate.Meta {
+	return predicate.Meta(func(s *sql.Selector) {
+		s.Where(sql.NotNull(s.C(FieldUpdatedAt)))
+	})
+}
+
 // KeyEQ applies the EQ predicate on the "key" field.
 func KeyEQ(v string) predicate.Meta {
 	return predicate.Meta(func(s *sql.Selector) {

+ 2 - 8
pkg/database/ent/meta_create.go

@@ -163,12 +163,6 @@ func (mc *MetaCreate) defaults() {
 
 // check runs all checks and user-defined validators on the builder.
 func (mc *MetaCreate) check() error {
-	if _, ok := mc.mutation.CreatedAt(); !ok {
-		return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)}
-	}
-	if _, ok := mc.mutation.UpdatedAt(); !ok {
-		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)}
-	}
 	if _, ok := mc.mutation.Key(); !ok {
 		return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "key"`)}
 	}
@@ -213,7 +207,7 @@ func (mc *MetaCreate) createSpec() (*Meta, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: meta.FieldCreatedAt,
 		})
-		_node.CreatedAt = value
+		_node.CreatedAt = &value
 	}
 	if value, ok := mc.mutation.UpdatedAt(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
@@ -221,7 +215,7 @@ func (mc *MetaCreate) createSpec() (*Meta, *sqlgraph.CreateSpec) {
 			Value:  value,
 			Column: meta.FieldUpdatedAt,
 		})
-		_node.UpdatedAt = value
+		_node.UpdatedAt = &value
 	}
 	if value, ok := mc.mutation.Key(); ok {
 		_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{

+ 62 - 20
pkg/database/ent/meta_update.go

@@ -34,11 +34,9 @@ func (mu *MetaUpdate) SetCreatedAt(t time.Time) *MetaUpdate {
 	return mu
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (mu *MetaUpdate) SetNillableCreatedAt(t *time.Time) *MetaUpdate {
-	if t != nil {
-		mu.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (mu *MetaUpdate) ClearCreatedAt() *MetaUpdate {
+	mu.mutation.ClearCreatedAt()
 	return mu
 }
 
@@ -48,11 +46,9 @@ func (mu *MetaUpdate) SetUpdatedAt(t time.Time) *MetaUpdate {
 	return mu
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (mu *MetaUpdate) SetNillableUpdatedAt(t *time.Time) *MetaUpdate {
-	if t != nil {
-		mu.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (mu *MetaUpdate) ClearUpdatedAt() *MetaUpdate {
+	mu.mutation.ClearUpdatedAt()
 	return mu
 }
 
@@ -104,6 +100,7 @@ func (mu *MetaUpdate) Save(ctx context.Context) (int, error) {
 		err      error
 		affected int
 	)
+	mu.defaults()
 	if len(mu.hooks) == 0 {
 		if err = mu.check(); err != nil {
 			return 0, err
@@ -158,6 +155,18 @@ func (mu *MetaUpdate) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (mu *MetaUpdate) defaults() {
+	if _, ok := mu.mutation.CreatedAt(); !ok && !mu.mutation.CreatedAtCleared() {
+		v := meta.UpdateDefaultCreatedAt()
+		mu.mutation.SetCreatedAt(v)
+	}
+	if _, ok := mu.mutation.UpdatedAt(); !ok && !mu.mutation.UpdatedAtCleared() {
+		v := meta.UpdateDefaultUpdatedAt()
+		mu.mutation.SetUpdatedAt(v)
+	}
+}
+
 // check runs all checks and user-defined validators on the builder.
 func (mu *MetaUpdate) check() error {
 	if v, ok := mu.mutation.Value(); ok {
@@ -193,6 +202,12 @@ func (mu *MetaUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: meta.FieldCreatedAt,
 		})
 	}
+	if mu.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: meta.FieldCreatedAt,
+		})
+	}
 	if value, ok := mu.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -200,6 +215,12 @@ func (mu *MetaUpdate) sqlSave(ctx context.Context) (n int, err error) {
 			Column: meta.FieldUpdatedAt,
 		})
 	}
+	if mu.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: meta.FieldUpdatedAt,
+		})
+	}
 	if value, ok := mu.mutation.Key(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeString,
@@ -274,11 +295,9 @@ func (muo *MetaUpdateOne) SetCreatedAt(t time.Time) *MetaUpdateOne {
 	return muo
 }
 
-// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
-func (muo *MetaUpdateOne) SetNillableCreatedAt(t *time.Time) *MetaUpdateOne {
-	if t != nil {
-		muo.SetCreatedAt(*t)
-	}
+// ClearCreatedAt clears the value of the "created_at" field.
+func (muo *MetaUpdateOne) ClearCreatedAt() *MetaUpdateOne {
+	muo.mutation.ClearCreatedAt()
 	return muo
 }
 
@@ -288,11 +307,9 @@ func (muo *MetaUpdateOne) SetUpdatedAt(t time.Time) *MetaUpdateOne {
 	return muo
 }
 
-// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
-func (muo *MetaUpdateOne) SetNillableUpdatedAt(t *time.Time) *MetaUpdateOne {
-	if t != nil {
-		muo.SetUpdatedAt(*t)
-	}
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (muo *MetaUpdateOne) ClearUpdatedAt() *MetaUpdateOne {
+	muo.mutation.ClearUpdatedAt()
 	return muo
 }
 
@@ -351,6 +368,7 @@ func (muo *MetaUpdateOne) Save(ctx context.Context) (*Meta, error) {
 		err  error
 		node *Meta
 	)
+	muo.defaults()
 	if len(muo.hooks) == 0 {
 		if err = muo.check(); err != nil {
 			return nil, err
@@ -405,6 +423,18 @@ func (muo *MetaUpdateOne) ExecX(ctx context.Context) {
 	}
 }
 
+// defaults sets the default values of the builder before save.
+func (muo *MetaUpdateOne) defaults() {
+	if _, ok := muo.mutation.CreatedAt(); !ok && !muo.mutation.CreatedAtCleared() {
+		v := meta.UpdateDefaultCreatedAt()
+		muo.mutation.SetCreatedAt(v)
+	}
+	if _, ok := muo.mutation.UpdatedAt(); !ok && !muo.mutation.UpdatedAtCleared() {
+		v := meta.UpdateDefaultUpdatedAt()
+		muo.mutation.SetUpdatedAt(v)
+	}
+}
+
 // check runs all checks and user-defined validators on the builder.
 func (muo *MetaUpdateOne) check() error {
 	if v, ok := muo.mutation.Value(); ok {
@@ -457,6 +487,12 @@ func (muo *MetaUpdateOne) sqlSave(ctx context.Context) (_node *Meta, err error)
 			Column: meta.FieldCreatedAt,
 		})
 	}
+	if muo.mutation.CreatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: meta.FieldCreatedAt,
+		})
+	}
 	if value, ok := muo.mutation.UpdatedAt(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeTime,
@@ -464,6 +500,12 @@ func (muo *MetaUpdateOne) sqlSave(ctx context.Context) (_node *Meta, err error)
 			Column: meta.FieldUpdatedAt,
 		})
 	}
+	if muo.mutation.UpdatedAtCleared() {
+		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
+			Type:   field.TypeTime,
+			Column: meta.FieldUpdatedAt,
+		})
+	}
 	if value, ok := muo.mutation.Key(); ok {
 		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
 			Type:   field.TypeString,

+ 12 - 12
pkg/database/ent/migrate/schema.go

@@ -11,8 +11,8 @@ var (
 	// AlertsColumns holds the columns for the "alerts" table.
 	AlertsColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
-		{Name: "created_at", Type: field.TypeTime},
-		{Name: "updated_at", Type: field.TypeTime},
+		{Name: "created_at", Type: field.TypeTime, Nullable: true},
+		{Name: "updated_at", Type: field.TypeTime, Nullable: true},
 		{Name: "scenario", Type: field.TypeString},
 		{Name: "bucket_id", Type: field.TypeString, Nullable: true, Default: ""},
 		{Name: "message", Type: field.TypeString, Nullable: true, Default: ""},
@@ -59,8 +59,8 @@ var (
 	// BouncersColumns holds the columns for the "bouncers" table.
 	BouncersColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
-		{Name: "created_at", Type: field.TypeTime},
-		{Name: "updated_at", Type: field.TypeTime},
+		{Name: "created_at", Type: field.TypeTime, Nullable: true},
+		{Name: "updated_at", Type: field.TypeTime, Nullable: true},
 		{Name: "name", Type: field.TypeString, Unique: true},
 		{Name: "api_key", Type: field.TypeString},
 		{Name: "revoked", Type: field.TypeBool},
@@ -79,8 +79,8 @@ var (
 	// DecisionsColumns holds the columns for the "decisions" table.
 	DecisionsColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
-		{Name: "created_at", Type: field.TypeTime},
-		{Name: "updated_at", Type: field.TypeTime},
+		{Name: "created_at", Type: field.TypeTime, Nullable: true},
+		{Name: "updated_at", Type: field.TypeTime, Nullable: true},
 		{Name: "until", Type: field.TypeTime},
 		{Name: "scenario", Type: field.TypeString},
 		{Name: "type", Type: field.TypeString},
@@ -112,8 +112,8 @@ var (
 	// EventsColumns holds the columns for the "events" table.
 	EventsColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
-		{Name: "created_at", Type: field.TypeTime},
-		{Name: "updated_at", Type: field.TypeTime},
+		{Name: "created_at", Type: field.TypeTime, Nullable: true},
+		{Name: "updated_at", Type: field.TypeTime, Nullable: true},
 		{Name: "time", Type: field.TypeTime},
 		{Name: "serialized", Type: field.TypeString, Size: 8191},
 		{Name: "alert_events", Type: field.TypeInt, Nullable: true},
@@ -135,8 +135,8 @@ var (
 	// MachinesColumns holds the columns for the "machines" table.
 	MachinesColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
-		{Name: "created_at", Type: field.TypeTime},
-		{Name: "updated_at", Type: field.TypeTime},
+		{Name: "created_at", Type: field.TypeTime, Nullable: true},
+		{Name: "updated_at", Type: field.TypeTime, Nullable: true},
 		{Name: "last_push", Type: field.TypeTime, Nullable: true},
 		{Name: "machine_id", Type: field.TypeString, Unique: true},
 		{Name: "password", Type: field.TypeString},
@@ -155,8 +155,8 @@ var (
 	// MetaColumns holds the columns for the "meta" table.
 	MetaColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeInt, Increment: true},
-		{Name: "created_at", Type: field.TypeTime},
-		{Name: "updated_at", Type: field.TypeTime},
+		{Name: "created_at", Type: field.TypeTime, Nullable: true},
+		{Name: "updated_at", Type: field.TypeTime, Nullable: true},
 		{Name: "key", Type: field.TypeString},
 		{Name: "value", Type: field.TypeString, Size: 4095},
 		{Name: "alert_metas", Type: field.TypeInt, Nullable: true},

+ 249 - 15
pkg/database/ent/mutation.go

@@ -181,7 +181,7 @@ func (m *AlertMutation) CreatedAt() (r time.Time, exists bool) {
 // OldCreatedAt returns the old "created_at" field's value of the Alert entity.
 // If the Alert object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *AlertMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *AlertMutation) OldCreatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations")
 	}
@@ -195,9 +195,22 @@ func (m *AlertMutation) OldCreatedAt(ctx context.Context) (v time.Time, err erro
 	return oldValue.CreatedAt, nil
 }
 
+// ClearCreatedAt clears the value of the "created_at" field.
+func (m *AlertMutation) ClearCreatedAt() {
+	m.created_at = nil
+	m.clearedFields[alert.FieldCreatedAt] = struct{}{}
+}
+
+// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
+func (m *AlertMutation) CreatedAtCleared() bool {
+	_, ok := m.clearedFields[alert.FieldCreatedAt]
+	return ok
+}
+
 // ResetCreatedAt resets all changes to the "created_at" field.
 func (m *AlertMutation) ResetCreatedAt() {
 	m.created_at = nil
+	delete(m.clearedFields, alert.FieldCreatedAt)
 }
 
 // SetUpdatedAt sets the "updated_at" field.
@@ -217,7 +230,7 @@ func (m *AlertMutation) UpdatedAt() (r time.Time, exists bool) {
 // OldUpdatedAt returns the old "updated_at" field's value of the Alert entity.
 // If the Alert object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *AlertMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *AlertMutation) OldUpdatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations")
 	}
@@ -231,9 +244,22 @@ func (m *AlertMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err erro
 	return oldValue.UpdatedAt, nil
 }
 
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (m *AlertMutation) ClearUpdatedAt() {
+	m.updated_at = nil
+	m.clearedFields[alert.FieldUpdatedAt] = struct{}{}
+}
+
+// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
+func (m *AlertMutation) UpdatedAtCleared() bool {
+	_, ok := m.clearedFields[alert.FieldUpdatedAt]
+	return ok
+}
+
 // ResetUpdatedAt resets all changes to the "updated_at" field.
 func (m *AlertMutation) ResetUpdatedAt() {
 	m.updated_at = nil
+	delete(m.clearedFields, alert.FieldUpdatedAt)
 }
 
 // SetScenario sets the "scenario" field.
@@ -1910,6 +1936,12 @@ func (m *AlertMutation) AddField(name string, value ent.Value) error {
 // mutation.
 func (m *AlertMutation) ClearedFields() []string {
 	var fields []string
+	if m.FieldCleared(alert.FieldCreatedAt) {
+		fields = append(fields, alert.FieldCreatedAt)
+	}
+	if m.FieldCleared(alert.FieldUpdatedAt) {
+		fields = append(fields, alert.FieldUpdatedAt)
+	}
 	if m.FieldCleared(alert.FieldBucketId) {
 		fields = append(fields, alert.FieldBucketId)
 	}
@@ -1978,6 +2010,12 @@ func (m *AlertMutation) FieldCleared(name string) bool {
 // error if the field is not defined in the schema.
 func (m *AlertMutation) ClearField(name string) error {
 	switch name {
+	case alert.FieldCreatedAt:
+		m.ClearCreatedAt()
+		return nil
+	case alert.FieldUpdatedAt:
+		m.ClearUpdatedAt()
+		return nil
 	case alert.FieldBucketId:
 		m.ClearBucketId()
 		return nil
@@ -2382,7 +2420,7 @@ func (m *BouncerMutation) CreatedAt() (r time.Time, exists bool) {
 // OldCreatedAt returns the old "created_at" field's value of the Bouncer entity.
 // If the Bouncer object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *BouncerMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *BouncerMutation) OldCreatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations")
 	}
@@ -2396,9 +2434,22 @@ func (m *BouncerMutation) OldCreatedAt(ctx context.Context) (v time.Time, err er
 	return oldValue.CreatedAt, nil
 }
 
+// ClearCreatedAt clears the value of the "created_at" field.
+func (m *BouncerMutation) ClearCreatedAt() {
+	m.created_at = nil
+	m.clearedFields[bouncer.FieldCreatedAt] = struct{}{}
+}
+
+// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
+func (m *BouncerMutation) CreatedAtCleared() bool {
+	_, ok := m.clearedFields[bouncer.FieldCreatedAt]
+	return ok
+}
+
 // ResetCreatedAt resets all changes to the "created_at" field.
 func (m *BouncerMutation) ResetCreatedAt() {
 	m.created_at = nil
+	delete(m.clearedFields, bouncer.FieldCreatedAt)
 }
 
 // SetUpdatedAt sets the "updated_at" field.
@@ -2418,7 +2469,7 @@ func (m *BouncerMutation) UpdatedAt() (r time.Time, exists bool) {
 // OldUpdatedAt returns the old "updated_at" field's value of the Bouncer entity.
 // If the Bouncer object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *BouncerMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *BouncerMutation) OldUpdatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations")
 	}
@@ -2432,9 +2483,22 @@ func (m *BouncerMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err er
 	return oldValue.UpdatedAt, nil
 }
 
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (m *BouncerMutation) ClearUpdatedAt() {
+	m.updated_at = nil
+	m.clearedFields[bouncer.FieldUpdatedAt] = struct{}{}
+}
+
+// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
+func (m *BouncerMutation) UpdatedAtCleared() bool {
+	_, ok := m.clearedFields[bouncer.FieldUpdatedAt]
+	return ok
+}
+
 // ResetUpdatedAt resets all changes to the "updated_at" field.
 func (m *BouncerMutation) ResetUpdatedAt() {
 	m.updated_at = nil
+	delete(m.clearedFields, bouncer.FieldUpdatedAt)
 }
 
 // SetName sets the "name" field.
@@ -2993,6 +3057,12 @@ func (m *BouncerMutation) AddField(name string, value ent.Value) error {
 // mutation.
 func (m *BouncerMutation) ClearedFields() []string {
 	var fields []string
+	if m.FieldCleared(bouncer.FieldCreatedAt) {
+		fields = append(fields, bouncer.FieldCreatedAt)
+	}
+	if m.FieldCleared(bouncer.FieldUpdatedAt) {
+		fields = append(fields, bouncer.FieldUpdatedAt)
+	}
 	if m.FieldCleared(bouncer.FieldIPAddress) {
 		fields = append(fields, bouncer.FieldIPAddress)
 	}
@@ -3019,6 +3089,12 @@ func (m *BouncerMutation) FieldCleared(name string) bool {
 // error if the field is not defined in the schema.
 func (m *BouncerMutation) ClearField(name string) error {
 	switch name {
+	case bouncer.FieldCreatedAt:
+		m.ClearCreatedAt()
+		return nil
+	case bouncer.FieldUpdatedAt:
+		m.ClearUpdatedAt()
+		return nil
 	case bouncer.FieldIPAddress:
 		m.ClearIPAddress()
 		return nil
@@ -3250,7 +3326,7 @@ func (m *DecisionMutation) CreatedAt() (r time.Time, exists bool) {
 // OldCreatedAt returns the old "created_at" field's value of the Decision entity.
 // If the Decision object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *DecisionMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *DecisionMutation) OldCreatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations")
 	}
@@ -3264,9 +3340,22 @@ func (m *DecisionMutation) OldCreatedAt(ctx context.Context) (v time.Time, err e
 	return oldValue.CreatedAt, nil
 }
 
+// ClearCreatedAt clears the value of the "created_at" field.
+func (m *DecisionMutation) ClearCreatedAt() {
+	m.created_at = nil
+	m.clearedFields[decision.FieldCreatedAt] = struct{}{}
+}
+
+// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
+func (m *DecisionMutation) CreatedAtCleared() bool {
+	_, ok := m.clearedFields[decision.FieldCreatedAt]
+	return ok
+}
+
 // ResetCreatedAt resets all changes to the "created_at" field.
 func (m *DecisionMutation) ResetCreatedAt() {
 	m.created_at = nil
+	delete(m.clearedFields, decision.FieldCreatedAt)
 }
 
 // SetUpdatedAt sets the "updated_at" field.
@@ -3286,7 +3375,7 @@ func (m *DecisionMutation) UpdatedAt() (r time.Time, exists bool) {
 // OldUpdatedAt returns the old "updated_at" field's value of the Decision entity.
 // If the Decision object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *DecisionMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *DecisionMutation) OldUpdatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations")
 	}
@@ -3300,9 +3389,22 @@ func (m *DecisionMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err e
 	return oldValue.UpdatedAt, nil
 }
 
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (m *DecisionMutation) ClearUpdatedAt() {
+	m.updated_at = nil
+	m.clearedFields[decision.FieldUpdatedAt] = struct{}{}
+}
+
+// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
+func (m *DecisionMutation) UpdatedAtCleared() bool {
+	_, ok := m.clearedFields[decision.FieldUpdatedAt]
+	return ok
+}
+
 // ResetUpdatedAt resets all changes to the "updated_at" field.
 func (m *DecisionMutation) ResetUpdatedAt() {
 	m.updated_at = nil
+	delete(m.clearedFields, decision.FieldUpdatedAt)
 }
 
 // SetUntil sets the "until" field.
@@ -4281,6 +4383,12 @@ func (m *DecisionMutation) AddField(name string, value ent.Value) error {
 // mutation.
 func (m *DecisionMutation) ClearedFields() []string {
 	var fields []string
+	if m.FieldCleared(decision.FieldCreatedAt) {
+		fields = append(fields, decision.FieldCreatedAt)
+	}
+	if m.FieldCleared(decision.FieldUpdatedAt) {
+		fields = append(fields, decision.FieldUpdatedAt)
+	}
 	if m.FieldCleared(decision.FieldStartIP) {
 		fields = append(fields, decision.FieldStartIP)
 	}
@@ -4310,6 +4418,12 @@ func (m *DecisionMutation) FieldCleared(name string) bool {
 // error if the field is not defined in the schema.
 func (m *DecisionMutation) ClearField(name string) error {
 	switch name {
+	case decision.FieldCreatedAt:
+		m.ClearCreatedAt()
+		return nil
+	case decision.FieldUpdatedAt:
+		m.ClearUpdatedAt()
+		return nil
 	case decision.FieldStartIP:
 		m.ClearStartIP()
 		return nil
@@ -4569,7 +4683,7 @@ func (m *EventMutation) CreatedAt() (r time.Time, exists bool) {
 // OldCreatedAt returns the old "created_at" field's value of the Event entity.
 // If the Event object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *EventMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *EventMutation) OldCreatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations")
 	}
@@ -4583,9 +4697,22 @@ func (m *EventMutation) OldCreatedAt(ctx context.Context) (v time.Time, err erro
 	return oldValue.CreatedAt, nil
 }
 
+// ClearCreatedAt clears the value of the "created_at" field.
+func (m *EventMutation) ClearCreatedAt() {
+	m.created_at = nil
+	m.clearedFields[event.FieldCreatedAt] = struct{}{}
+}
+
+// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
+func (m *EventMutation) CreatedAtCleared() bool {
+	_, ok := m.clearedFields[event.FieldCreatedAt]
+	return ok
+}
+
 // ResetCreatedAt resets all changes to the "created_at" field.
 func (m *EventMutation) ResetCreatedAt() {
 	m.created_at = nil
+	delete(m.clearedFields, event.FieldCreatedAt)
 }
 
 // SetUpdatedAt sets the "updated_at" field.
@@ -4605,7 +4732,7 @@ func (m *EventMutation) UpdatedAt() (r time.Time, exists bool) {
 // OldUpdatedAt returns the old "updated_at" field's value of the Event entity.
 // If the Event object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *EventMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *EventMutation) OldUpdatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations")
 	}
@@ -4619,9 +4746,22 @@ func (m *EventMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err erro
 	return oldValue.UpdatedAt, nil
 }
 
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (m *EventMutation) ClearUpdatedAt() {
+	m.updated_at = nil
+	m.clearedFields[event.FieldUpdatedAt] = struct{}{}
+}
+
+// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
+func (m *EventMutation) UpdatedAtCleared() bool {
+	_, ok := m.clearedFields[event.FieldUpdatedAt]
+	return ok
+}
+
 // ResetUpdatedAt resets all changes to the "updated_at" field.
 func (m *EventMutation) ResetUpdatedAt() {
 	m.updated_at = nil
+	delete(m.clearedFields, event.FieldUpdatedAt)
 }
 
 // SetTime sets the "time" field.
@@ -4866,7 +5006,14 @@ func (m *EventMutation) AddField(name string, value ent.Value) error {
 // ClearedFields returns all nullable fields that were cleared during this
 // mutation.
 func (m *EventMutation) ClearedFields() []string {
-	return nil
+	var fields []string
+	if m.FieldCleared(event.FieldCreatedAt) {
+		fields = append(fields, event.FieldCreatedAt)
+	}
+	if m.FieldCleared(event.FieldUpdatedAt) {
+		fields = append(fields, event.FieldUpdatedAt)
+	}
+	return fields
 }
 
 // FieldCleared returns a boolean indicating if a field with the given name was
@@ -4879,6 +5026,14 @@ func (m *EventMutation) FieldCleared(name string) bool {
 // ClearField clears the value of the field with the given name. It returns an
 // error if the field is not defined in the schema.
 func (m *EventMutation) ClearField(name string) error {
+	switch name {
+	case event.FieldCreatedAt:
+		m.ClearCreatedAt()
+		return nil
+	case event.FieldUpdatedAt:
+		m.ClearUpdatedAt()
+		return nil
+	}
 	return fmt.Errorf("unknown Event nullable field %s", name)
 }
 
@@ -5099,7 +5254,7 @@ func (m *MachineMutation) CreatedAt() (r time.Time, exists bool) {
 // OldCreatedAt returns the old "created_at" field's value of the Machine entity.
 // If the Machine object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *MachineMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *MachineMutation) OldCreatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations")
 	}
@@ -5113,9 +5268,22 @@ func (m *MachineMutation) OldCreatedAt(ctx context.Context) (v time.Time, err er
 	return oldValue.CreatedAt, nil
 }
 
+// ClearCreatedAt clears the value of the "created_at" field.
+func (m *MachineMutation) ClearCreatedAt() {
+	m.created_at = nil
+	m.clearedFields[machine.FieldCreatedAt] = struct{}{}
+}
+
+// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
+func (m *MachineMutation) CreatedAtCleared() bool {
+	_, ok := m.clearedFields[machine.FieldCreatedAt]
+	return ok
+}
+
 // ResetCreatedAt resets all changes to the "created_at" field.
 func (m *MachineMutation) ResetCreatedAt() {
 	m.created_at = nil
+	delete(m.clearedFields, machine.FieldCreatedAt)
 }
 
 // SetUpdatedAt sets the "updated_at" field.
@@ -5135,7 +5303,7 @@ func (m *MachineMutation) UpdatedAt() (r time.Time, exists bool) {
 // OldUpdatedAt returns the old "updated_at" field's value of the Machine entity.
 // If the Machine object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *MachineMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *MachineMutation) OldUpdatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations")
 	}
@@ -5149,9 +5317,22 @@ func (m *MachineMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err er
 	return oldValue.UpdatedAt, nil
 }
 
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (m *MachineMutation) ClearUpdatedAt() {
+	m.updated_at = nil
+	m.clearedFields[machine.FieldUpdatedAt] = struct{}{}
+}
+
+// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
+func (m *MachineMutation) UpdatedAtCleared() bool {
+	_, ok := m.clearedFields[machine.FieldUpdatedAt]
+	return ok
+}
+
 // ResetUpdatedAt resets all changes to the "updated_at" field.
 func (m *MachineMutation) ResetUpdatedAt() {
 	m.updated_at = nil
+	delete(m.clearedFields, machine.FieldUpdatedAt)
 }
 
 // SetLastPush sets the "last_push" field.
@@ -5171,7 +5352,7 @@ func (m *MachineMutation) LastPush() (r time.Time, exists bool) {
 // OldLastPush returns the old "last_push" field's value of the Machine entity.
 // If the Machine object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *MachineMutation) OldLastPush(ctx context.Context) (v time.Time, err error) {
+func (m *MachineMutation) OldLastPush(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldLastPush is only allowed on UpdateOne operations")
 	}
@@ -5764,6 +5945,12 @@ func (m *MachineMutation) AddField(name string, value ent.Value) error {
 // mutation.
 func (m *MachineMutation) ClearedFields() []string {
 	var fields []string
+	if m.FieldCleared(machine.FieldCreatedAt) {
+		fields = append(fields, machine.FieldCreatedAt)
+	}
+	if m.FieldCleared(machine.FieldUpdatedAt) {
+		fields = append(fields, machine.FieldUpdatedAt)
+	}
 	if m.FieldCleared(machine.FieldLastPush) {
 		fields = append(fields, machine.FieldLastPush)
 	}
@@ -5790,6 +5977,12 @@ func (m *MachineMutation) FieldCleared(name string) bool {
 // error if the field is not defined in the schema.
 func (m *MachineMutation) ClearField(name string) error {
 	switch name {
+	case machine.FieldCreatedAt:
+		m.ClearCreatedAt()
+		return nil
+	case machine.FieldUpdatedAt:
+		m.ClearUpdatedAt()
+		return nil
 	case machine.FieldLastPush:
 		m.ClearLastPush()
 		return nil
@@ -6042,7 +6235,7 @@ func (m *MetaMutation) CreatedAt() (r time.Time, exists bool) {
 // OldCreatedAt returns the old "created_at" field's value of the Meta entity.
 // If the Meta object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *MetaMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *MetaMutation) OldCreatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations")
 	}
@@ -6056,9 +6249,22 @@ func (m *MetaMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error
 	return oldValue.CreatedAt, nil
 }
 
+// ClearCreatedAt clears the value of the "created_at" field.
+func (m *MetaMutation) ClearCreatedAt() {
+	m.created_at = nil
+	m.clearedFields[meta.FieldCreatedAt] = struct{}{}
+}
+
+// CreatedAtCleared returns if the "created_at" field was cleared in this mutation.
+func (m *MetaMutation) CreatedAtCleared() bool {
+	_, ok := m.clearedFields[meta.FieldCreatedAt]
+	return ok
+}
+
 // ResetCreatedAt resets all changes to the "created_at" field.
 func (m *MetaMutation) ResetCreatedAt() {
 	m.created_at = nil
+	delete(m.clearedFields, meta.FieldCreatedAt)
 }
 
 // SetUpdatedAt sets the "updated_at" field.
@@ -6078,7 +6284,7 @@ func (m *MetaMutation) UpdatedAt() (r time.Time, exists bool) {
 // OldUpdatedAt returns the old "updated_at" field's value of the Meta entity.
 // If the Meta object wasn't provided to the builder, the object is fetched from the database.
 // An error is returned if the mutation operation is not UpdateOne, or the database query fails.
-func (m *MetaMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
+func (m *MetaMutation) OldUpdatedAt(ctx context.Context) (v *time.Time, err error) {
 	if !m.op.Is(OpUpdateOne) {
 		return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations")
 	}
@@ -6092,9 +6298,22 @@ func (m *MetaMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error
 	return oldValue.UpdatedAt, nil
 }
 
+// ClearUpdatedAt clears the value of the "updated_at" field.
+func (m *MetaMutation) ClearUpdatedAt() {
+	m.updated_at = nil
+	m.clearedFields[meta.FieldUpdatedAt] = struct{}{}
+}
+
+// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
+func (m *MetaMutation) UpdatedAtCleared() bool {
+	_, ok := m.clearedFields[meta.FieldUpdatedAt]
+	return ok
+}
+
 // ResetUpdatedAt resets all changes to the "updated_at" field.
 func (m *MetaMutation) ResetUpdatedAt() {
 	m.updated_at = nil
+	delete(m.clearedFields, meta.FieldUpdatedAt)
 }
 
 // SetKey sets the "key" field.
@@ -6339,7 +6558,14 @@ func (m *MetaMutation) AddField(name string, value ent.Value) error {
 // ClearedFields returns all nullable fields that were cleared during this
 // mutation.
 func (m *MetaMutation) ClearedFields() []string {
-	return nil
+	var fields []string
+	if m.FieldCleared(meta.FieldCreatedAt) {
+		fields = append(fields, meta.FieldCreatedAt)
+	}
+	if m.FieldCleared(meta.FieldUpdatedAt) {
+		fields = append(fields, meta.FieldUpdatedAt)
+	}
+	return fields
 }
 
 // FieldCleared returns a boolean indicating if a field with the given name was
@@ -6352,6 +6578,14 @@ func (m *MetaMutation) FieldCleared(name string) bool {
 // ClearField clears the value of the field with the given name. It returns an
 // error if the field is not defined in the schema.
 func (m *MetaMutation) ClearField(name string) error {
+	switch name {
+	case meta.FieldCreatedAt:
+		m.ClearCreatedAt()
+		return nil
+	case meta.FieldUpdatedAt:
+		m.ClearUpdatedAt()
+		return nil
+	}
 	return fmt.Errorf("unknown Meta nullable field %s", name)
 }
 

+ 26 - 0
pkg/database/ent/runtime.go

@@ -24,10 +24,14 @@ func init() {
 	alertDescCreatedAt := alertFields[0].Descriptor()
 	// alert.DefaultCreatedAt holds the default value on creation for the created_at field.
 	alert.DefaultCreatedAt = alertDescCreatedAt.Default.(func() time.Time)
+	// alert.UpdateDefaultCreatedAt holds the default value on update for the created_at field.
+	alert.UpdateDefaultCreatedAt = alertDescCreatedAt.UpdateDefault.(func() time.Time)
 	// alertDescUpdatedAt is the schema descriptor for updated_at field.
 	alertDescUpdatedAt := alertFields[1].Descriptor()
 	// alert.DefaultUpdatedAt holds the default value on creation for the updated_at field.
 	alert.DefaultUpdatedAt = alertDescUpdatedAt.Default.(func() time.Time)
+	// alert.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	alert.UpdateDefaultUpdatedAt = alertDescUpdatedAt.UpdateDefault.(func() time.Time)
 	// alertDescBucketId is the schema descriptor for bucketId field.
 	alertDescBucketId := alertFields[3].Descriptor()
 	// alert.DefaultBucketId holds the default value on creation for the bucketId field.
@@ -58,10 +62,14 @@ func init() {
 	bouncerDescCreatedAt := bouncerFields[0].Descriptor()
 	// bouncer.DefaultCreatedAt holds the default value on creation for the created_at field.
 	bouncer.DefaultCreatedAt = bouncerDescCreatedAt.Default.(func() time.Time)
+	// bouncer.UpdateDefaultCreatedAt holds the default value on update for the created_at field.
+	bouncer.UpdateDefaultCreatedAt = bouncerDescCreatedAt.UpdateDefault.(func() time.Time)
 	// bouncerDescUpdatedAt is the schema descriptor for updated_at field.
 	bouncerDescUpdatedAt := bouncerFields[1].Descriptor()
 	// bouncer.DefaultUpdatedAt holds the default value on creation for the updated_at field.
 	bouncer.DefaultUpdatedAt = bouncerDescUpdatedAt.Default.(func() time.Time)
+	// bouncer.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	bouncer.UpdateDefaultUpdatedAt = bouncerDescUpdatedAt.UpdateDefault.(func() time.Time)
 	// bouncerDescIPAddress is the schema descriptor for ip_address field.
 	bouncerDescIPAddress := bouncerFields[5].Descriptor()
 	// bouncer.DefaultIPAddress holds the default value on creation for the ip_address field.
@@ -80,10 +88,14 @@ func init() {
 	decisionDescCreatedAt := decisionFields[0].Descriptor()
 	// decision.DefaultCreatedAt holds the default value on creation for the created_at field.
 	decision.DefaultCreatedAt = decisionDescCreatedAt.Default.(func() time.Time)
+	// decision.UpdateDefaultCreatedAt holds the default value on update for the created_at field.
+	decision.UpdateDefaultCreatedAt = decisionDescCreatedAt.UpdateDefault.(func() time.Time)
 	// decisionDescUpdatedAt is the schema descriptor for updated_at field.
 	decisionDescUpdatedAt := decisionFields[1].Descriptor()
 	// decision.DefaultUpdatedAt holds the default value on creation for the updated_at field.
 	decision.DefaultUpdatedAt = decisionDescUpdatedAt.Default.(func() time.Time)
+	// decision.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	decision.UpdateDefaultUpdatedAt = decisionDescUpdatedAt.UpdateDefault.(func() time.Time)
 	// decisionDescSimulated is the schema descriptor for simulated field.
 	decisionDescSimulated := decisionFields[13].Descriptor()
 	// decision.DefaultSimulated holds the default value on creation for the simulated field.
@@ -94,10 +106,14 @@ func init() {
 	eventDescCreatedAt := eventFields[0].Descriptor()
 	// event.DefaultCreatedAt holds the default value on creation for the created_at field.
 	event.DefaultCreatedAt = eventDescCreatedAt.Default.(func() time.Time)
+	// event.UpdateDefaultCreatedAt holds the default value on update for the created_at field.
+	event.UpdateDefaultCreatedAt = eventDescCreatedAt.UpdateDefault.(func() time.Time)
 	// eventDescUpdatedAt is the schema descriptor for updated_at field.
 	eventDescUpdatedAt := eventFields[1].Descriptor()
 	// event.DefaultUpdatedAt holds the default value on creation for the updated_at field.
 	event.DefaultUpdatedAt = eventDescUpdatedAt.Default.(func() time.Time)
+	// event.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	event.UpdateDefaultUpdatedAt = eventDescUpdatedAt.UpdateDefault.(func() time.Time)
 	// eventDescSerialized is the schema descriptor for serialized field.
 	eventDescSerialized := eventFields[3].Descriptor()
 	// event.SerializedValidator is a validator for the "serialized" field. It is called by the builders before save.
@@ -108,14 +124,20 @@ func init() {
 	machineDescCreatedAt := machineFields[0].Descriptor()
 	// machine.DefaultCreatedAt holds the default value on creation for the created_at field.
 	machine.DefaultCreatedAt = machineDescCreatedAt.Default.(func() time.Time)
+	// machine.UpdateDefaultCreatedAt holds the default value on update for the created_at field.
+	machine.UpdateDefaultCreatedAt = machineDescCreatedAt.UpdateDefault.(func() time.Time)
 	// machineDescUpdatedAt is the schema descriptor for updated_at field.
 	machineDescUpdatedAt := machineFields[1].Descriptor()
 	// machine.DefaultUpdatedAt holds the default value on creation for the updated_at field.
 	machine.DefaultUpdatedAt = machineDescUpdatedAt.Default.(func() time.Time)
+	// machine.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	machine.UpdateDefaultUpdatedAt = machineDescUpdatedAt.UpdateDefault.(func() time.Time)
 	// machineDescLastPush is the schema descriptor for last_push field.
 	machineDescLastPush := machineFields[2].Descriptor()
 	// machine.DefaultLastPush holds the default value on creation for the last_push field.
 	machine.DefaultLastPush = machineDescLastPush.Default.(func() time.Time)
+	// machine.UpdateDefaultLastPush holds the default value on update for the last_push field.
+	machine.UpdateDefaultLastPush = machineDescLastPush.UpdateDefault.(func() time.Time)
 	// machineDescScenarios is the schema descriptor for scenarios field.
 	machineDescScenarios := machineFields[6].Descriptor()
 	// machine.ScenariosValidator is a validator for the "scenarios" field. It is called by the builders before save.
@@ -130,10 +152,14 @@ func init() {
 	metaDescCreatedAt := metaFields[0].Descriptor()
 	// meta.DefaultCreatedAt holds the default value on creation for the created_at field.
 	meta.DefaultCreatedAt = metaDescCreatedAt.Default.(func() time.Time)
+	// meta.UpdateDefaultCreatedAt holds the default value on update for the created_at field.
+	meta.UpdateDefaultCreatedAt = metaDescCreatedAt.UpdateDefault.(func() time.Time)
 	// metaDescUpdatedAt is the schema descriptor for updated_at field.
 	metaDescUpdatedAt := metaFields[1].Descriptor()
 	// meta.DefaultUpdatedAt holds the default value on creation for the updated_at field.
 	meta.DefaultUpdatedAt = metaDescUpdatedAt.Default.(func() time.Time)
+	// meta.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
+	meta.UpdateDefaultUpdatedAt = metaDescUpdatedAt.UpdateDefault.(func() time.Time)
 	// metaDescValue is the schema descriptor for value field.
 	metaDescValue := metaFields[3].Descriptor()
 	// meta.ValueValidator is a validator for the "value" field. It is called by the builders before save.

+ 7 - 6
pkg/database/ent/schema/alert.go

@@ -1,13 +1,12 @@
 package schema
 
 import (
-	"time"
-
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/entsql"
 	"entgo.io/ent/schema/edge"
 	"entgo.io/ent/schema/field"
 	"entgo.io/ent/schema/index"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 // Alert holds the schema definition for the Alert entity.
@@ -19,15 +18,17 @@ type Alert struct {
 func (Alert) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("created_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("updated_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.String("scenario"),
 		field.String("bucketId").Default("").Optional(),
 		field.String("message").Default("").Optional(),
 		field.Int32("eventsCount").Default(0).Optional(),
-		field.Time("startedAt").Default(time.Now).Optional(),
-		field.Time("stoppedAt").Default(time.Now).Optional(),
+		field.Time("startedAt").Default(types.UtcNow).Optional(),
+		field.Time("stoppedAt").Default(types.UtcNow).Optional(),
 		field.String("sourceIp").
 			Optional(),
 		field.String("sourceRange").

+ 7 - 6
pkg/database/ent/schema/bouncer.go

@@ -1,10 +1,9 @@
 package schema
 
 import (
-	"time"
-
 	"entgo.io/ent"
 	"entgo.io/ent/schema/field"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 // Bouncer holds the schema definition for the Bouncer entity.
@@ -16,18 +15,20 @@ type Bouncer struct {
 func (Bouncer) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("created_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("updated_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.String("name").Unique(),
 		field.String("api_key"), // hash of api_key
 		field.Bool("revoked"),
 		field.String("ip_address").Default("").Optional(),
 		field.String("type").Optional(),
 		field.String("version").Optional(),
-		field.Time("until").Default(time.Now).Optional(),
+		field.Time("until").Default(types.UtcNow).Optional(),
 		field.Time("last_pull").
-			Default(time.Now),
+			Default(types.UtcNow),
 	}
 }
 

+ 5 - 4
pkg/database/ent/schema/decision.go

@@ -1,11 +1,10 @@
 package schema
 
 import (
-	"time"
-
 	"entgo.io/ent"
 	"entgo.io/ent/schema/edge"
 	"entgo.io/ent/schema/field"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 // Decision holds the schema definition for the Decision entity.
@@ -17,9 +16,11 @@ type Decision struct {
 func (Decision) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("created_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("updated_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("until"),
 		field.String("scenario"),
 		field.String("type"),

+ 5 - 4
pkg/database/ent/schema/event.go

@@ -1,11 +1,10 @@
 package schema
 
 import (
-	"time"
-
 	"entgo.io/ent"
 	"entgo.io/ent/schema/edge"
 	"entgo.io/ent/schema/field"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 // Event holds the schema definition for the Event entity.
@@ -17,9 +16,11 @@ type Event struct {
 func (Event) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("created_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("updated_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("time"),
 		field.String("serialized").MaxLen(8191),
 	}

+ 7 - 5
pkg/database/ent/schema/machine.go

@@ -1,11 +1,10 @@
 package schema
 
 import (
-	"time"
-
 	"entgo.io/ent"
 	"entgo.io/ent/schema/edge"
 	"entgo.io/ent/schema/field"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 // Machine holds the schema definition for the Machine entity.
@@ -17,11 +16,14 @@ type Machine struct {
 func (Machine) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("created_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("updated_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("last_push").
-			Default(time.Now).Optional(),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.String("machineId").Unique(),
 		field.String("password").Sensitive(),
 		field.String("ipAddress"),

+ 5 - 4
pkg/database/ent/schema/meta.go

@@ -1,11 +1,10 @@
 package schema
 
 import (
-	"time"
-
 	"entgo.io/ent"
 	"entgo.io/ent/schema/edge"
 	"entgo.io/ent/schema/field"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 // Meta holds the schema definition for the Meta entity.
@@ -17,9 +16,11 @@ type Meta struct {
 func (Meta) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("created_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.Time("updated_at").
-			Default(time.Now),
+			Default(types.UtcNow).
+			UpdateDefault(types.UtcNow).Nillable().Optional(),
 		field.String("key"),
 		field.String("value").MaxLen(4095),
 	}

+ 2 - 2
pkg/database/machines.go

@@ -111,7 +111,7 @@ func (c *Client) DeleteWatcher(name string) error {
 }
 
 func (c *Client) UpdateMachineLastPush(machineID string) error {
-	_, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(machineID)).SetLastPush(time.Now()).Save(c.CTX)
+	_, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(machineID)).SetLastPush(time.Now().UTC()).Save(c.CTX)
 	if err != nil {
 		return errors.Wrapf(UpdateFail, "updating machine last_push: %s", err)
 	}
@@ -120,7 +120,7 @@ func (c *Client) UpdateMachineLastPush(machineID string) error {
 
 func (c *Client) UpdateMachineScenarios(scenarios string, ID int) error {
 	_, err := c.Ent.Machine.UpdateOneID(ID).
-		SetUpdatedAt(time.Now()).
+		SetUpdatedAt(time.Now().UTC()).
 		SetScenarios(scenarios).
 		Save(c.CTX)
 	if err != nil {

+ 1 - 1
pkg/exprhelpers/exprlib.go

@@ -176,7 +176,7 @@ func IpInRange(ip string, ipRange string) bool {
 }
 
 func TimeNow() string {
-	return time.Now().Format(time.RFC3339)
+	return time.Now().UTC().Format(time.RFC3339)
 }
 
 func ParseUri(uri string) map[string][]string {

+ 1 - 1
pkg/exprhelpers/exprlib_test.go

@@ -381,7 +381,7 @@ func TestTimeNow(t *testing.T) {
 	}
 
 	if -1*time.Until(ti) > time.Second {
-		t.Fatalf("TimeNow func should return time.Now()")
+		t.Fatalf("TimeNow func should return time.Now().UTC()")
 	}
 	log.Printf("test 'TimeNow()' : OK")
 }

+ 4 - 4
pkg/leakybucket/bucket.go

@@ -261,7 +261,7 @@ func LeakRoutine(leaky *Leaky) error {
 				alert types.RuntimeAlert
 				err   error
 			)
-			leaky.Ovflw_ts = time.Now()
+			leaky.Ovflw_ts = time.Now().UTC()
 			close(leaky.Signal)
 			ofw := leaky.Queue
 			alert = types.RuntimeAlert{Mapkey: leaky.Mapkey}
@@ -315,13 +315,13 @@ func Pour(leaky *Leaky, msg types.Event) {
 
 	leaky.Total_count += 1
 	if leaky.First_ts.IsZero() {
-		leaky.First_ts = time.Now()
+		leaky.First_ts = time.Now().UTC()
 	}
-	leaky.Last_ts = time.Now()
+	leaky.Last_ts = time.Now().UTC()
 	if leaky.Limiter.Allow() {
 		leaky.Queue.Add(msg)
 	} else {
-		leaky.Ovflw_ts = time.Now()
+		leaky.Ovflw_ts = time.Now().UTC()
 		leaky.logger.Debugf("Last event to be poured, bucket overflow.")
 		leaky.Queue.Add(msg)
 		leaky.Out <- leaky.Queue

+ 2 - 2
pkg/leakybucket/manager_run.go

@@ -163,12 +163,12 @@ func PourItemToBucket(bucket *Leaky, holder BucketFactory, buckets *Buckets, par
 	sigclosed := 0
 	failed_sent := 0
 	attempts := 0
-	start := time.Now()
+	start := time.Now().UTC()
 
 	for !sent {
 		attempts += 1
 		/* Warn the user if we used more than a 100 ms to pour an event, it's at least an half lock*/
-		if attempts%100000 == 0 && start.Add(100*time.Millisecond).Before(time.Now()) {
+		if attempts%100000 == 0 && start.Add(100*time.Millisecond).Before(time.Now().UTC()) {
 			holder.logger.Warningf("stuck for %s sending event to %s (sigclosed:%d failed_sent:%d attempts:%d)", time.Since(start),
 				buckey, sigclosed, failed_sent, attempts)
 		}

+ 2 - 2
pkg/leakybucket/manager_run_test.go

@@ -98,7 +98,7 @@ func TestGCandDump(t *testing.T) {
 	log.Printf("Bucket GC")
 
 	//call garbage collector
-	if err := GarbageCollectBuckets(time.Now(), buckets); err != nil {
+	if err := GarbageCollectBuckets(time.Now().UTC(), buckets); err != nil {
 		t.Fatalf("failed to garbage collect buckets : %s", err)
 	}
 
@@ -108,7 +108,7 @@ func TestGCandDump(t *testing.T) {
 
 	log.Printf("Dumping buckets state")
 	//dump remaining buckets
-	if _, err := DumpBucketsStateAt(time.Now(), ".", buckets); err != nil {
+	if _, err := DumpBucketsStateAt(time.Now().UTC(), ".", buckets); err != nil {
 		t.Fatalf("failed to dump buckets : %s", err)
 	}
 }

+ 1 - 1
pkg/leakybucket/overflows.go

@@ -166,7 +166,7 @@ func EventsFromQueue(queue *Queue) []*models.Event {
 		//either MarshaledTime is present and is extracted from log
 		if evt.MarshaledTime != "" {
 			ovflwEvent.Timestamp = &evt.MarshaledTime
-		} else if !evt.Time.IsZero() { //or .Time has been set during parse as time.Now()
+		} else if !evt.Time.IsZero() { //or .Time has been set during parse as time.Now().UTC()
 			ovflwEvent.Timestamp = new(string)
 			raw, err := evt.Time.MarshalText()
 			if err != nil {

+ 4 - 4
pkg/leakybucket/trigger.go

@@ -20,16 +20,16 @@ func (t *Trigger) OnBucketPour(b *BucketFactory) func(types.Event, *Leaky) *type
 			err := d.UnmarshalText([]byte(msg.MarshaledTime))
 			if err != nil {
 				log.Warningf("Failed unmarshaling event time (%s) : %v", msg.MarshaledTime, err)
-				d = time.Now()
+				d = time.Now().UTC()
 			}
 			l.logger.Debugf("yay timemachine overflow time : %s --> %s", d, msg.MarshaledTime)
 			l.Last_ts = d
 			l.First_ts = d
 			l.Ovflw_ts = d
 		} else {
-			l.Last_ts = time.Now()
-			l.First_ts = time.Now()
-			l.Ovflw_ts = time.Now()
+			l.Last_ts = time.Now().UTC()
+			l.First_ts = time.Now().UTC()
+			l.Ovflw_ts = time.Now().UTC()
 		}
 		l.Total_count = 1
 

+ 2 - 2
pkg/parser/enrich_date.go

@@ -33,7 +33,7 @@ func GenDateParse(date string) (string, time.Time) {
 		if err == nil && !t.IsZero() {
 			//if the year isn't set, set it to current date :)
 			if t.Year() == 0 {
-				t = t.AddDate(time.Now().Year(), 0, 0)
+				t = t.AddDate(time.Now().UTC().Year(), 0, 0)
 			}
 			retstr, err := t.MarshalText()
 			if err != nil {
@@ -44,7 +44,7 @@ func GenDateParse(date string) (string, time.Time) {
 		}
 	}
 
-	now := time.Now()
+	now := time.Now().UTC()
 	retstr, err := now.MarshalText()
 	if err != nil {
 		log.Warningf("Failed marshaling current time")

+ 1 - 1
pkg/parser/runtime.go

@@ -239,7 +239,7 @@ func Parse(ctx UnixParserCtx, xp types.Event, nodes []Node) (types.Event, error)
 	}
 	event.Process = false
 	if event.Time.IsZero() {
-		event.Time = time.Now()
+		event.Time = time.Now().UTC()
 	}
 
 	if event.Parsed == nil {

+ 1 - 0
pkg/time/rate/rate_test.go

@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.7
 // +build go1.7
 
 package rate

+ 4 - 0
pkg/types/utils.go

@@ -235,3 +235,7 @@ func InSlice(str string, slice []string) bool {
 	}
 	return false
 }
+
+func UtcNow() time.Time {
+	return time.Now().UTC()
+}