Handle decisions with varying expiry for same IP (#1262)
* Upgrade ent and add sql/modifier in codegen * update db wrappers to sanitize LAPI Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
This commit is contained in:
parent
d18620858e
commit
e4f6cdfc14
29 changed files with 1120 additions and 227 deletions
43
go.mod
43
go.mod
|
@ -3,7 +3,7 @@ module github.com/crowdsecurity/crowdsec
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
entgo.io/ent v0.9.1
|
||||
entgo.io/ent v0.10.0
|
||||
github.com/AlecAivazis/survey/v2 v2.2.7
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible
|
||||
github.com/ahmetb/dlog v0.0.0-20170105205344-4fb5f8204f26
|
||||
|
@ -21,23 +21,23 @@ require (
|
|||
github.com/docker/go-connections v0.4.0
|
||||
github.com/enescakir/emoji v1.0.0
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/go-co-op/gocron v1.9.0
|
||||
github.com/go-openapi/errors v0.20.1
|
||||
github.com/go-openapi/strfmt v0.19.11
|
||||
github.com/go-openapi/swag v0.19.12
|
||||
github.com/go-openapi/validate v0.20.0
|
||||
github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/google/go-querystring v1.0.0
|
||||
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e
|
||||
github.com/hashicorp/go-hclog v0.14.1
|
||||
github.com/hashicorp/go-hclog v1.0.0
|
||||
github.com/hashicorp/go-plugin v1.4.2
|
||||
github.com/hashicorp/go-version v1.2.1
|
||||
github.com/influxdata/go-syslog/v3 v3.0.0
|
||||
github.com/jszwec/csvutil v1.5.1
|
||||
github.com/lib/pq v1.10.2
|
||||
github.com/mattn/go-sqlite3 v1.14.8
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/mattn/go-sqlite3 v1.14.10
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||
github.com/nxadm/tail v1.4.6
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
|
@ -49,11 +49,11 @@ require (
|
|||
github.com/prometheus/prom2json v1.3.0
|
||||
github.com/r3labs/diff/v2 v2.14.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.1.3
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/spf13/cobra v1.3.0
|
||||
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce
|
||||
golang.org/x/mod v0.4.2
|
||||
google.golang.org/grpc v1.35.0
|
||||
golang.org/x/mod v0.5.1
|
||||
google.golang.org/grpc v1.42.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
|
||||
|
@ -62,22 +62,26 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.3.2-0.20220120225051-c3fac7d636dd // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/ahmetalpbalkan/dlog v0.0.0-20170105205344-4fb5f8204f26 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/c-robinson/iplib v1.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/containerd/containerd v1.4.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-openapi/analysis v0.19.16 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
||||
github.com/go-openapi/loads v0.20.0 // indirect
|
||||
|
@ -90,8 +94,9 @@ require (
|
|||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.5 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.10.0 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
|
@ -110,14 +115,15 @@ require (
|
|||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
|
@ -137,14 +143,17 @@ require (
|
|||
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||
github.com/vjeantet/grok v1.0.1 // indirect
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.4.4 // indirect
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/appengine v1.6.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f // indirect
|
||||
golang.org/x/tools v0.1.9-0.20211216111533-8d383106f7e7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
|
|
@ -267,7 +267,7 @@ func TestGetDecision(t *testing.T) {
|
|||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "\"id\":1,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]")
|
||||
assert.Contains(t, w.Body.String(), "\"id\":3,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]")
|
||||
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,7 @@ func TestDeleteDecision(t *testing.T) {
|
|||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, "{\"nbDeleted\":\"1\"}", w.Body.String())
|
||||
assert.Equal(t, "{\"nbDeleted\":\"3\"}", w.Body.String())
|
||||
|
||||
}
|
||||
|
||||
|
@ -431,6 +431,56 @@ func TestStreamDecision(t *testing.T) {
|
|||
req.Header.Add("X-Api-Key", APIKey)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
// the decision with id=3 is only returned because it's the longest decision
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "\"id\":1,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]}")
|
||||
assert.Contains(t, w.Body.String(), "\"id\":3,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]}")
|
||||
assert.NotContains(t, w.Body.String(), "\"id\":2")
|
||||
assert.NotContains(t, w.Body.String(), "\"id\":1")
|
||||
assert.Contains(t, w.Body.String(), "2h")
|
||||
|
||||
// id=3 decision is deleted, this won't affect `deleted`, because there are decisions
|
||||
// targetting same IP
|
||||
req, _ = http.NewRequest("DELETE", "/v1/decisions/3", strings.NewReader(""))
|
||||
AddAuthHeaders(req, loginResp)
|
||||
router.ServeHTTP(w, req)
|
||||
assert.Equal(t, 200, w.Code)
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest("GET", "/v1/decisions/stream?startup=true", strings.NewReader(""))
|
||||
req.Header.Add("X-Api-Key", APIKey)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
// the decision with id=2 is only returned because it's the longest decision
|
||||
assert.Contains(t, w.Body.String(), "\"id\":2,\"origin\":\"test\",\"scenario\":\"crowdsecurity/test\",\"scope\":\"Ip\",\"type\":\"ban\",\"value\":\"127.0.0.1\"}]}")
|
||||
assert.NotContains(t, w.Body.String(), "\"id\":3")
|
||||
assert.NotContains(t, w.Body.String(), "\"id\":1")
|
||||
assert.Contains(t, w.Body.String(), "1h")
|
||||
assert.Contains(t, w.Body.String(), "\"deleted\":null")
|
||||
|
||||
// We delete another decision, yet don't receive it in stream, since there's another decision on same IP
|
||||
req, _ = http.NewRequest("DELETE", "/v1/decisions/2", strings.NewReader(""))
|
||||
AddAuthHeaders(req, loginResp)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest("GET", "/v1/decisions/stream", strings.NewReader(""))
|
||||
req.Header.Add("X-Api-Key", APIKey)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, "{\"deleted\":null,\"new\":null}", w.Body.String())
|
||||
|
||||
// Now all decisions for this IP are deleted, we should receive it in stream
|
||||
req, _ = http.NewRequest("DELETE", "/v1/decisions/1", strings.NewReader(""))
|
||||
AddAuthHeaders(req, loginResp)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest("GET", "/v1/decisions/stream", strings.NewReader(""))
|
||||
req.Header.Add("X-Api-Key", APIKey)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.NotContains(t, "\"deleted\":null", w.Body.String())
|
||||
}
|
||||
|
|
|
@ -13,6 +13,24 @@
|
|||
"scope": "Ip",
|
||||
"value": "127.0.0.1",
|
||||
"type": "ban"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"duration": "2h",
|
||||
"origin": "test",
|
||||
"scenario": "crowdsecurity/test",
|
||||
"scope": "Ip",
|
||||
"value": "127.0.0.1",
|
||||
"type": "ban"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"duration": "3h",
|
||||
"origin": "test",
|
||||
"scenario": "crowdsecurity/test",
|
||||
"scope": "Ip",
|
||||
"value": "127.0.0.1",
|
||||
"type": "ban"
|
||||
}
|
||||
],
|
||||
"Events": [
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"strconv"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent/decision"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
|
@ -170,8 +171,35 @@ func (c *Client) QueryDecisionWithFilter(filter map[string][]string) ([]*ent.Dec
|
|||
return data, nil
|
||||
}
|
||||
|
||||
// Groups by (decision.scope, decision.type, decision.value)
|
||||
func decisionGroupBy(s *sql.Selector) {
|
||||
s.GroupBy(
|
||||
decision.FieldScope,
|
||||
decision.FieldType,
|
||||
decision.FieldValue,
|
||||
)
|
||||
}
|
||||
|
||||
// Gets decisions where all (decision.scope, decision.type, decision.value) tuples are unique.
|
||||
// The decision with maximum duration would be included if it's not expired.
|
||||
func (c *Client) QueryAllDecisionsWithFilters(filters map[string][]string) ([]*ent.Decision, error) {
|
||||
query := c.Ent.Decision.Query().Where(decision.UntilGT(time.Now().UTC()))
|
||||
decisionModifier := func(s *sql.Selector) {
|
||||
decisionGroupBy(s)
|
||||
s.Having(
|
||||
sql.And(
|
||||
sql.EQ(
|
||||
decision.FieldUntil,
|
||||
sql.Raw(sql.Max(decision.FieldUntil)),
|
||||
),
|
||||
sql.GT(
|
||||
decision.FieldUntil,
|
||||
time.Now().UTC(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
query := c.Ent.Decision.Query().Modify(decisionModifier).Where()
|
||||
|
||||
query, err := BuildDecisionRequestWithFilter(query, filters)
|
||||
|
||||
if err != nil {
|
||||
|
@ -188,7 +216,24 @@ 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().UTC()))
|
||||
|
||||
decisionModifier := func(s *sql.Selector) {
|
||||
decisionGroupBy(s)
|
||||
s.Having(
|
||||
sql.And(
|
||||
sql.EQ(
|
||||
decision.FieldUntil,
|
||||
sql.Raw(sql.Max(decision.FieldUntil)),
|
||||
),
|
||||
sql.LT(
|
||||
decision.FieldUntil,
|
||||
time.Now().UTC(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
query := c.Ent.Decision.Query().Modify(decisionModifier).Where()
|
||||
query, err := BuildDecisionRequestWithFilter(query, filters)
|
||||
|
||||
if err != nil {
|
||||
|
@ -204,7 +249,32 @@ 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().UTC())).Where(decision.UntilGT(since))
|
||||
decisionModifier := func(s *sql.Selector) {
|
||||
decisionGroupBy(s)
|
||||
s.Having(
|
||||
sql.And(
|
||||
sql.EQ(
|
||||
decision.FieldUntil,
|
||||
sql.Raw(sql.Max(decision.FieldUntil)), // It has max duration
|
||||
),
|
||||
sql.GT(
|
||||
decision.FieldUntil, // It was active at t=since
|
||||
since,
|
||||
),
|
||||
sql.LT(
|
||||
decision.FieldUntil, // It is expired as of now
|
||||
time.Now().UTC(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// This query returns 1 decision for each (decision.scope, decision.type, decision.value)
|
||||
// if all decisions for the tuple are dead. Else it gives 0 decisions.
|
||||
query := c.Ent.Decision.Query().Modify(
|
||||
decisionModifier,
|
||||
).Where()
|
||||
|
||||
query, err := BuildDecisionRequestWithFilter(query, filters)
|
||||
if err != nil {
|
||||
c.Log.Warningf("QueryExpiredDecisionsSinceWithFilters : %s", err)
|
||||
|
@ -221,7 +291,26 @@ 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().UTC()))
|
||||
decisionModifier := func(s *sql.Selector) {
|
||||
decisionGroupBy(s)
|
||||
s.Having(
|
||||
sql.And(
|
||||
sql.EQ(
|
||||
decision.FieldUntil,
|
||||
sql.Raw(sql.Max(decision.FieldUntil)),
|
||||
),
|
||||
sql.GT(
|
||||
decision.FieldCreatedAt,
|
||||
since,
|
||||
),
|
||||
sql.GT(
|
||||
decision.FieldUntil,
|
||||
time.Now().UTC(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
query := c.Ent.Decision.Query().Modify(decisionModifier).Where()
|
||||
query, err := BuildDecisionRequestWithFilter(query, filters)
|
||||
if err != nil {
|
||||
c.Log.Warningf("QueryNewDecisionsSinceWithFilters : %s", err)
|
||||
|
|
|
@ -496,10 +496,10 @@ func (ac *AlertCreate) defaults() {
|
|||
// check runs all checks and user-defined validators on the builder.
|
||||
func (ac *AlertCreate) check() error {
|
||||
if _, ok := ac.mutation.Scenario(); !ok {
|
||||
return &ValidationError{Name: "scenario", err: errors.New(`ent: missing required field "scenario"`)}
|
||||
return &ValidationError{Name: "scenario", err: errors.New(`ent: missing required field "Alert.scenario"`)}
|
||||
}
|
||||
if _, ok := ac.mutation.Simulated(); !ok {
|
||||
return &ValidationError{Name: "simulated", err: errors.New(`ent: missing required field "simulated"`)}
|
||||
return &ValidationError{Name: "simulated", err: errors.New(`ent: missing required field "Alert.simulated"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ type AlertQuery struct {
|
|||
withEvents *EventQuery
|
||||
withMetas *MetaQuery
|
||||
withFKs bool
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
|
@ -486,6 +487,9 @@ func (aq *AlertQuery) sqlAll(ctx context.Context) ([]*Alert, error) {
|
|||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(aq.modifiers) > 0 {
|
||||
_spec.Modifiers = aq.modifiers
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, aq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -614,6 +618,13 @@ func (aq *AlertQuery) sqlAll(ctx context.Context) ([]*Alert, error) {
|
|||
|
||||
func (aq *AlertQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := aq.querySpec()
|
||||
if len(aq.modifiers) > 0 {
|
||||
_spec.Modifiers = aq.modifiers
|
||||
}
|
||||
_spec.Node.Columns = aq.fields
|
||||
if len(aq.fields) > 0 {
|
||||
_spec.Unique = aq.unique != nil && *aq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, aq.driver, _spec)
|
||||
}
|
||||
|
||||
|
@ -685,6 +696,12 @@ func (aq *AlertQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
selector = aq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if aq.unique != nil && *aq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range aq.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range aq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
|
@ -702,6 +719,12 @@ func (aq *AlertQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
return selector
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (aq *AlertQuery) Modify(modifiers ...func(s *sql.Selector)) *AlertSelect {
|
||||
aq.modifiers = append(aq.modifiers, modifiers...)
|
||||
return aq.Select()
|
||||
}
|
||||
|
||||
// AlertGroupBy is the group-by builder for Alert entities.
|
||||
type AlertGroupBy struct {
|
||||
config
|
||||
|
@ -963,9 +986,7 @@ func (agb *AlertGroupBy) sqlQuery() *sql.Selector {
|
|||
for _, f := range agb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
for _, c := range aggregation {
|
||||
columns = append(columns, c)
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(agb.fields...)...)
|
||||
|
@ -1191,3 +1212,9 @@ func (as *AlertSelect) sqlScan(ctx context.Context, v interface{}) error {
|
|||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (as *AlertSelect) Modify(modifiers ...func(s *sql.Selector)) *AlertSelect {
|
||||
as.modifiers = append(as.modifiers, modifiers...)
|
||||
return as
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -1861,7 +1862,7 @@ func (auo *AlertUpdateOne) sqlSave(ctx context.Context) (_node *Alert, err error
|
|||
}
|
||||
id, ok := auo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Alert.ID for update")}
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Alert.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := auo.fields; len(fields) > 0 {
|
||||
|
|
|
@ -232,16 +232,16 @@ func (bc *BouncerCreate) defaults() {
|
|||
// check runs all checks and user-defined validators on the builder.
|
||||
func (bc *BouncerCreate) check() error {
|
||||
if _, ok := bc.mutation.Name(); !ok {
|
||||
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "name"`)}
|
||||
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "Bouncer.name"`)}
|
||||
}
|
||||
if _, ok := bc.mutation.APIKey(); !ok {
|
||||
return &ValidationError{Name: "api_key", err: errors.New(`ent: missing required field "api_key"`)}
|
||||
return &ValidationError{Name: "api_key", err: errors.New(`ent: missing required field "Bouncer.api_key"`)}
|
||||
}
|
||||
if _, ok := bc.mutation.Revoked(); !ok {
|
||||
return &ValidationError{Name: "revoked", err: errors.New(`ent: missing required field "revoked"`)}
|
||||
return &ValidationError{Name: "revoked", err: errors.New(`ent: missing required field "Bouncer.revoked"`)}
|
||||
}
|
||||
if _, ok := bc.mutation.LastPull(); !ok {
|
||||
return &ValidationError{Name: "last_pull", err: errors.New(`ent: missing required field "last_pull"`)}
|
||||
return &ValidationError{Name: "last_pull", err: errors.New(`ent: missing required field "Bouncer.last_pull"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ type BouncerQuery struct {
|
|||
order []OrderFunc
|
||||
fields []string
|
||||
predicates []predicate.Bouncer
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
|
@ -325,6 +326,9 @@ func (bq *BouncerQuery) sqlAll(ctx context.Context) ([]*Bouncer, error) {
|
|||
node := nodes[len(nodes)-1]
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(bq.modifiers) > 0 {
|
||||
_spec.Modifiers = bq.modifiers
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, bq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -336,6 +340,13 @@ func (bq *BouncerQuery) sqlAll(ctx context.Context) ([]*Bouncer, error) {
|
|||
|
||||
func (bq *BouncerQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := bq.querySpec()
|
||||
if len(bq.modifiers) > 0 {
|
||||
_spec.Modifiers = bq.modifiers
|
||||
}
|
||||
_spec.Node.Columns = bq.fields
|
||||
if len(bq.fields) > 0 {
|
||||
_spec.Unique = bq.unique != nil && *bq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, bq.driver, _spec)
|
||||
}
|
||||
|
||||
|
@ -407,6 +418,12 @@ func (bq *BouncerQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
selector = bq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if bq.unique != nil && *bq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range bq.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range bq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
|
@ -424,6 +441,12 @@ func (bq *BouncerQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
return selector
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (bq *BouncerQuery) Modify(modifiers ...func(s *sql.Selector)) *BouncerSelect {
|
||||
bq.modifiers = append(bq.modifiers, modifiers...)
|
||||
return bq.Select()
|
||||
}
|
||||
|
||||
// BouncerGroupBy is the group-by builder for Bouncer entities.
|
||||
type BouncerGroupBy struct {
|
||||
config
|
||||
|
@ -685,9 +708,7 @@ func (bgb *BouncerGroupBy) sqlQuery() *sql.Selector {
|
|||
for _, f := range bgb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
for _, c := range aggregation {
|
||||
columns = append(columns, c)
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(bgb.fields...)...)
|
||||
|
@ -913,3 +934,9 @@ func (bs *BouncerSelect) sqlScan(ctx context.Context, v interface{}) error {
|
|||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (bs *BouncerSelect) Modify(modifiers ...func(s *sql.Selector)) *BouncerSelect {
|
||||
bs.modifiers = append(bs.modifiers, modifiers...)
|
||||
return bs
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -606,7 +607,7 @@ func (buo *BouncerUpdateOne) sqlSave(ctx context.Context) (_node *Bouncer, err e
|
|||
}
|
||||
id, ok := buo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Bouncer.ID for update")}
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Bouncer.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := buo.fields; len(fields) > 0 {
|
||||
|
|
|
@ -113,6 +113,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
|||
cfg := c.config
|
||||
cfg.driver = &txDriver{tx: tx, drv: c.driver}
|
||||
return &Tx{
|
||||
ctx: ctx,
|
||||
config: cfg,
|
||||
Alert: NewAlertClient(cfg),
|
||||
Bouncer: NewBouncerClient(cfg),
|
||||
|
|
|
@ -276,25 +276,25 @@ func (dc *DecisionCreate) defaults() {
|
|||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dc *DecisionCreate) check() error {
|
||||
if _, ok := dc.mutation.Until(); !ok {
|
||||
return &ValidationError{Name: "until", err: errors.New(`ent: missing required field "until"`)}
|
||||
return &ValidationError{Name: "until", err: errors.New(`ent: missing required field "Decision.until"`)}
|
||||
}
|
||||
if _, ok := dc.mutation.Scenario(); !ok {
|
||||
return &ValidationError{Name: "scenario", err: errors.New(`ent: missing required field "scenario"`)}
|
||||
return &ValidationError{Name: "scenario", err: errors.New(`ent: missing required field "Decision.scenario"`)}
|
||||
}
|
||||
if _, ok := dc.mutation.GetType(); !ok {
|
||||
return &ValidationError{Name: "type", err: errors.New(`ent: missing required field "type"`)}
|
||||
return &ValidationError{Name: "type", err: errors.New(`ent: missing required field "Decision.type"`)}
|
||||
}
|
||||
if _, ok := dc.mutation.Scope(); !ok {
|
||||
return &ValidationError{Name: "scope", err: errors.New(`ent: missing required field "scope"`)}
|
||||
return &ValidationError{Name: "scope", err: errors.New(`ent: missing required field "Decision.scope"`)}
|
||||
}
|
||||
if _, ok := dc.mutation.Value(); !ok {
|
||||
return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "value"`)}
|
||||
return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "Decision.value"`)}
|
||||
}
|
||||
if _, ok := dc.mutation.Origin(); !ok {
|
||||
return &ValidationError{Name: "origin", err: errors.New(`ent: missing required field "origin"`)}
|
||||
return &ValidationError{Name: "origin", err: errors.New(`ent: missing required field "Decision.origin"`)}
|
||||
}
|
||||
if _, ok := dc.mutation.Simulated(); !ok {
|
||||
return &ValidationError{Name: "simulated", err: errors.New(`ent: missing required field "simulated"`)}
|
||||
return &ValidationError{Name: "simulated", err: errors.New(`ent: missing required field "Decision.simulated"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ type DecisionQuery struct {
|
|||
// eager-loading edges.
|
||||
withOwner *AlertQuery
|
||||
withFKs bool
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
|
@ -374,6 +375,9 @@ func (dq *DecisionQuery) sqlAll(ctx context.Context) ([]*Decision, error) {
|
|||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(dq.modifiers) > 0 {
|
||||
_spec.Modifiers = dq.modifiers
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, dq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -415,6 +419,13 @@ func (dq *DecisionQuery) sqlAll(ctx context.Context) ([]*Decision, error) {
|
|||
|
||||
func (dq *DecisionQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := dq.querySpec()
|
||||
if len(dq.modifiers) > 0 {
|
||||
_spec.Modifiers = dq.modifiers
|
||||
}
|
||||
_spec.Node.Columns = dq.fields
|
||||
if len(dq.fields) > 0 {
|
||||
_spec.Unique = dq.unique != nil && *dq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, dq.driver, _spec)
|
||||
}
|
||||
|
||||
|
@ -486,6 +497,12 @@ func (dq *DecisionQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
selector = dq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if dq.unique != nil && *dq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range dq.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range dq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
|
@ -503,6 +520,12 @@ func (dq *DecisionQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
return selector
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (dq *DecisionQuery) Modify(modifiers ...func(s *sql.Selector)) *DecisionSelect {
|
||||
dq.modifiers = append(dq.modifiers, modifiers...)
|
||||
return dq.Select()
|
||||
}
|
||||
|
||||
// DecisionGroupBy is the group-by builder for Decision entities.
|
||||
type DecisionGroupBy struct {
|
||||
config
|
||||
|
@ -764,9 +787,7 @@ func (dgb *DecisionGroupBy) sqlQuery() *sql.Selector {
|
|||
for _, f := range dgb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
for _, c := range aggregation {
|
||||
columns = append(columns, c)
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(dgb.fields...)...)
|
||||
|
@ -992,3 +1013,9 @@ func (ds *DecisionSelect) sqlScan(ctx context.Context, v interface{}) error {
|
|||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (ds *DecisionSelect) Modify(modifiers ...func(s *sql.Selector)) *DecisionSelect {
|
||||
ds.modifiers = append(ds.modifiers, modifiers...)
|
||||
return ds
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -907,7 +908,7 @@ func (duo *DecisionUpdateOne) sqlSave(ctx context.Context) (_node *Decision, err
|
|||
}
|
||||
id, ok := duo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Decision.ID for update")}
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Decision.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := duo.fields; len(fields) > 0 {
|
||||
|
|
|
@ -151,7 +151,7 @@ func Sum(field string) AggregateFunc {
|
|||
}
|
||||
}
|
||||
|
||||
// ValidationError returns when validating a field fails.
|
||||
// ValidationError returns when validating a field or edge fails.
|
||||
type ValidationError struct {
|
||||
Name string // Field or edge name.
|
||||
err error
|
||||
|
|
|
@ -164,14 +164,14 @@ func (ec *EventCreate) defaults() {
|
|||
// check runs all checks and user-defined validators on the builder.
|
||||
func (ec *EventCreate) check() error {
|
||||
if _, ok := ec.mutation.Time(); !ok {
|
||||
return &ValidationError{Name: "time", err: errors.New(`ent: missing required field "time"`)}
|
||||
return &ValidationError{Name: "time", err: errors.New(`ent: missing required field "Event.time"`)}
|
||||
}
|
||||
if _, ok := ec.mutation.Serialized(); !ok {
|
||||
return &ValidationError{Name: "serialized", err: errors.New(`ent: missing required field "serialized"`)}
|
||||
return &ValidationError{Name: "serialized", err: errors.New(`ent: missing required field "Event.serialized"`)}
|
||||
}
|
||||
if v, ok := ec.mutation.Serialized(); ok {
|
||||
if err := event.SerializedValidator(v); err != nil {
|
||||
return &ValidationError{Name: "serialized", err: fmt.Errorf(`ent: validator failed for field "serialized": %w`, err)}
|
||||
return &ValidationError{Name: "serialized", err: fmt.Errorf(`ent: validator failed for field "Event.serialized": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -28,6 +28,7 @@ type EventQuery struct {
|
|||
// eager-loading edges.
|
||||
withOwner *AlertQuery
|
||||
withFKs bool
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
|
@ -374,6 +375,9 @@ func (eq *EventQuery) sqlAll(ctx context.Context) ([]*Event, error) {
|
|||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(eq.modifiers) > 0 {
|
||||
_spec.Modifiers = eq.modifiers
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, eq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -415,6 +419,13 @@ func (eq *EventQuery) sqlAll(ctx context.Context) ([]*Event, error) {
|
|||
|
||||
func (eq *EventQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := eq.querySpec()
|
||||
if len(eq.modifiers) > 0 {
|
||||
_spec.Modifiers = eq.modifiers
|
||||
}
|
||||
_spec.Node.Columns = eq.fields
|
||||
if len(eq.fields) > 0 {
|
||||
_spec.Unique = eq.unique != nil && *eq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, eq.driver, _spec)
|
||||
}
|
||||
|
||||
|
@ -486,6 +497,12 @@ func (eq *EventQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
selector = eq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if eq.unique != nil && *eq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range eq.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range eq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
|
@ -503,6 +520,12 @@ func (eq *EventQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
return selector
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (eq *EventQuery) Modify(modifiers ...func(s *sql.Selector)) *EventSelect {
|
||||
eq.modifiers = append(eq.modifiers, modifiers...)
|
||||
return eq.Select()
|
||||
}
|
||||
|
||||
// EventGroupBy is the group-by builder for Event entities.
|
||||
type EventGroupBy struct {
|
||||
config
|
||||
|
@ -764,9 +787,7 @@ func (egb *EventGroupBy) sqlQuery() *sql.Selector {
|
|||
for _, f := range egb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
for _, c := range aggregation {
|
||||
columns = append(columns, c)
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(egb.fields...)...)
|
||||
|
@ -992,3 +1013,9 @@ func (es *EventSelect) sqlScan(ctx context.Context, v interface{}) error {
|
|||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (es *EventSelect) Modify(modifiers ...func(s *sql.Selector)) *EventSelect {
|
||||
es.modifiers = append(es.modifiers, modifiers...)
|
||||
return es
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -171,7 +172,7 @@ func (eu *EventUpdate) defaults() {
|
|||
func (eu *EventUpdate) check() error {
|
||||
if v, ok := eu.mutation.Serialized(); ok {
|
||||
if err := event.SerializedValidator(v); err != nil {
|
||||
return &ValidationError{Name: "serialized", err: fmt.Errorf("ent: validator failed for field \"serialized\": %w", err)}
|
||||
return &ValidationError{Name: "serialized", err: fmt.Errorf(`ent: validator failed for field "Event.serialized": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -439,7 +440,7 @@ func (euo *EventUpdateOne) defaults() {
|
|||
func (euo *EventUpdateOne) check() error {
|
||||
if v, ok := euo.mutation.Serialized(); ok {
|
||||
if err := event.SerializedValidator(v); err != nil {
|
||||
return &ValidationError{Name: "serialized", err: fmt.Errorf("ent: validator failed for field \"serialized\": %w", err)}
|
||||
return &ValidationError{Name: "serialized", err: fmt.Errorf(`ent: validator failed for field "Event.serialized": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -458,7 +459,7 @@ func (euo *EventUpdateOne) sqlSave(ctx context.Context) (_node *Event, err error
|
|||
}
|
||||
id, ok := euo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Event.ID for update")}
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Event.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := euo.fields; len(fields) > 0 {
|
||||
|
|
|
@ -244,21 +244,21 @@ func (mc *MachineCreate) defaults() {
|
|||
// check runs all checks and user-defined validators on the builder.
|
||||
func (mc *MachineCreate) check() error {
|
||||
if _, ok := mc.mutation.MachineId(); !ok {
|
||||
return &ValidationError{Name: "machineId", err: errors.New(`ent: missing required field "machineId"`)}
|
||||
return &ValidationError{Name: "machineId", err: errors.New(`ent: missing required field "Machine.machineId"`)}
|
||||
}
|
||||
if _, ok := mc.mutation.Password(); !ok {
|
||||
return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "password"`)}
|
||||
return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "Machine.password"`)}
|
||||
}
|
||||
if _, ok := mc.mutation.IpAddress(); !ok {
|
||||
return &ValidationError{Name: "ipAddress", err: errors.New(`ent: missing required field "ipAddress"`)}
|
||||
return &ValidationError{Name: "ipAddress", err: errors.New(`ent: missing required field "Machine.ipAddress"`)}
|
||||
}
|
||||
if v, ok := mc.mutation.Scenarios(); ok {
|
||||
if err := machine.ScenariosValidator(v); err != nil {
|
||||
return &ValidationError{Name: "scenarios", err: fmt.Errorf(`ent: validator failed for field "scenarios": %w`, err)}
|
||||
return &ValidationError{Name: "scenarios", err: fmt.Errorf(`ent: validator failed for field "Machine.scenarios": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := mc.mutation.IsValidated(); !ok {
|
||||
return &ValidationError{Name: "isValidated", err: errors.New(`ent: missing required field "isValidated"`)}
|
||||
return &ValidationError{Name: "isValidated", err: errors.New(`ent: missing required field "Machine.isValidated"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ type MachineQuery struct {
|
|||
predicates []predicate.Machine
|
||||
// eager-loading edges.
|
||||
withAlerts *AlertQuery
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
|
@ -367,6 +368,9 @@ func (mq *MachineQuery) sqlAll(ctx context.Context) ([]*Machine, error) {
|
|||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(mq.modifiers) > 0 {
|
||||
_spec.Modifiers = mq.modifiers
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, mq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -408,6 +412,13 @@ func (mq *MachineQuery) sqlAll(ctx context.Context) ([]*Machine, error) {
|
|||
|
||||
func (mq *MachineQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := mq.querySpec()
|
||||
if len(mq.modifiers) > 0 {
|
||||
_spec.Modifiers = mq.modifiers
|
||||
}
|
||||
_spec.Node.Columns = mq.fields
|
||||
if len(mq.fields) > 0 {
|
||||
_spec.Unique = mq.unique != nil && *mq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, mq.driver, _spec)
|
||||
}
|
||||
|
||||
|
@ -479,6 +490,12 @@ func (mq *MachineQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
selector = mq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if mq.unique != nil && *mq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range mq.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range mq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
|
@ -496,6 +513,12 @@ func (mq *MachineQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
return selector
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (mq *MachineQuery) Modify(modifiers ...func(s *sql.Selector)) *MachineSelect {
|
||||
mq.modifiers = append(mq.modifiers, modifiers...)
|
||||
return mq.Select()
|
||||
}
|
||||
|
||||
// MachineGroupBy is the group-by builder for Machine entities.
|
||||
type MachineGroupBy struct {
|
||||
config
|
||||
|
@ -757,9 +780,7 @@ func (mgb *MachineGroupBy) sqlQuery() *sql.Selector {
|
|||
for _, f := range mgb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
for _, c := range aggregation {
|
||||
columns = append(columns, c)
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(mgb.fields...)...)
|
||||
|
@ -985,3 +1006,9 @@ func (ms *MachineSelect) sqlScan(ctx context.Context, v interface{}) error {
|
|||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (ms *MachineSelect) Modify(modifiers ...func(s *sql.Selector)) *MachineSelect {
|
||||
ms.modifiers = append(ms.modifiers, modifiers...)
|
||||
return ms
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -278,7 +279,7 @@ func (mu *MachineUpdate) defaults() {
|
|||
func (mu *MachineUpdate) check() error {
|
||||
if v, ok := mu.mutation.Scenarios(); ok {
|
||||
if err := machine.ScenariosValidator(v); err != nil {
|
||||
return &ValidationError{Name: "scenarios", err: fmt.Errorf("ent: validator failed for field \"scenarios\": %w", err)}
|
||||
return &ValidationError{Name: "scenarios", err: fmt.Errorf(`ent: validator failed for field "Machine.scenarios": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -738,7 +739,7 @@ func (muo *MachineUpdateOne) defaults() {
|
|||
func (muo *MachineUpdateOne) check() error {
|
||||
if v, ok := muo.mutation.Scenarios(); ok {
|
||||
if err := machine.ScenariosValidator(v); err != nil {
|
||||
return &ValidationError{Name: "scenarios", err: fmt.Errorf("ent: validator failed for field \"scenarios\": %w", err)}
|
||||
return &ValidationError{Name: "scenarios", err: fmt.Errorf(`ent: validator failed for field "Machine.scenarios": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -757,7 +758,7 @@ func (muo *MachineUpdateOne) sqlSave(ctx context.Context) (_node *Machine, err e
|
|||
}
|
||||
id, ok := muo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Machine.ID for update")}
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Machine.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := muo.fields; len(fields) > 0 {
|
||||
|
|
|
@ -164,14 +164,14 @@ func (mc *MetaCreate) defaults() {
|
|||
// check runs all checks and user-defined validators on the builder.
|
||||
func (mc *MetaCreate) check() error {
|
||||
if _, ok := mc.mutation.Key(); !ok {
|
||||
return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "key"`)}
|
||||
return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "Meta.key"`)}
|
||||
}
|
||||
if _, ok := mc.mutation.Value(); !ok {
|
||||
return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "value"`)}
|
||||
return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "Meta.value"`)}
|
||||
}
|
||||
if v, ok := mc.mutation.Value(); ok {
|
||||
if err := meta.ValueValidator(v); err != nil {
|
||||
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "value": %w`, err)}
|
||||
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Meta.value": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -28,6 +28,7 @@ type MetaQuery struct {
|
|||
// eager-loading edges.
|
||||
withOwner *AlertQuery
|
||||
withFKs bool
|
||||
modifiers []func(s *sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
|
@ -374,6 +375,9 @@ func (mq *MetaQuery) sqlAll(ctx context.Context) ([]*Meta, error) {
|
|||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(mq.modifiers) > 0 {
|
||||
_spec.Modifiers = mq.modifiers
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, mq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -415,6 +419,13 @@ func (mq *MetaQuery) sqlAll(ctx context.Context) ([]*Meta, error) {
|
|||
|
||||
func (mq *MetaQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := mq.querySpec()
|
||||
if len(mq.modifiers) > 0 {
|
||||
_spec.Modifiers = mq.modifiers
|
||||
}
|
||||
_spec.Node.Columns = mq.fields
|
||||
if len(mq.fields) > 0 {
|
||||
_spec.Unique = mq.unique != nil && *mq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, mq.driver, _spec)
|
||||
}
|
||||
|
||||
|
@ -486,6 +497,12 @@ func (mq *MetaQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
selector = mq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if mq.unique != nil && *mq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range mq.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range mq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
|
@ -503,6 +520,12 @@ func (mq *MetaQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
|||
return selector
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (mq *MetaQuery) Modify(modifiers ...func(s *sql.Selector)) *MetaSelect {
|
||||
mq.modifiers = append(mq.modifiers, modifiers...)
|
||||
return mq.Select()
|
||||
}
|
||||
|
||||
// MetaGroupBy is the group-by builder for Meta entities.
|
||||
type MetaGroupBy struct {
|
||||
config
|
||||
|
@ -764,9 +787,7 @@ func (mgb *MetaGroupBy) sqlQuery() *sql.Selector {
|
|||
for _, f := range mgb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
for _, c := range aggregation {
|
||||
columns = append(columns, c)
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(mgb.fields...)...)
|
||||
|
@ -992,3 +1013,9 @@ func (ms *MetaSelect) sqlScan(ctx context.Context, v interface{}) error {
|
|||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// Modify adds a query modifier for attaching custom logic to queries.
|
||||
func (ms *MetaSelect) Modify(modifiers ...func(s *sql.Selector)) *MetaSelect {
|
||||
ms.modifiers = append(ms.modifiers, modifiers...)
|
||||
return ms
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -171,7 +172,7 @@ func (mu *MetaUpdate) defaults() {
|
|||
func (mu *MetaUpdate) check() error {
|
||||
if v, ok := mu.mutation.Value(); ok {
|
||||
if err := meta.ValueValidator(v); err != nil {
|
||||
return &ValidationError{Name: "value", err: fmt.Errorf("ent: validator failed for field \"value\": %w", err)}
|
||||
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Meta.value": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -439,7 +440,7 @@ func (muo *MetaUpdateOne) defaults() {
|
|||
func (muo *MetaUpdateOne) check() error {
|
||||
if v, ok := muo.mutation.Value(); ok {
|
||||
if err := meta.ValueValidator(v); err != nil {
|
||||
return &ValidationError{Name: "value", err: fmt.Errorf("ent: validator failed for field \"value\": %w", err)}
|
||||
return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Meta.value": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -458,7 +459,7 @@ func (muo *MetaUpdateOne) sqlSave(ctx context.Context) (_node *Meta, err error)
|
|||
}
|
||||
id, ok := muo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Meta.ID for update")}
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Meta.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := muo.fields; len(fields) > 0 {
|
||||
|
|
|
@ -38,7 +38,6 @@ var (
|
|||
// Schema is the API for creating, migrating and dropping a schema.
|
||||
type Schema struct {
|
||||
drv dialect.Driver
|
||||
universalID bool
|
||||
}
|
||||
|
||||
// NewSchema creates a new schema client.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,6 +5,6 @@ package runtime
|
|||
// The schema-stitching logic is generated in github.com/crowdsecurity/crowdsec/pkg/database/ent/runtime.go
|
||||
|
||||
const (
|
||||
Version = "v0.9.1" // Version of ent codegen.
|
||||
Sum = "h1:IG8andyeD79GG24U8Q+1Y45hQXj6gY5evSBcva5gtBk=" // Sum of ent codegen.
|
||||
Version = "v0.10.0" // Version of ent codegen.
|
||||
Sum = "h1:9cBomE1fh+WX34DPYQL7tDNAIvhKa3tXvwxuLyhYCMo=" // Sum of ent codegen.
|
||||
)
|
||||
|
|
|
@ -40,7 +40,7 @@ type Tx struct {
|
|||
}
|
||||
|
||||
type (
|
||||
// Committer is the interface that wraps the Committer method.
|
||||
// Committer is the interface that wraps the Commit method.
|
||||
Committer interface {
|
||||
Commit(context.Context, *Tx) error
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ type (
|
|||
// and returns a Committer. For example:
|
||||
//
|
||||
// hook := func(next ent.Committer) ent.Committer {
|
||||
// return ent.CommitFunc(func(context.Context, tx *ent.Tx) error {
|
||||
// return ent.CommitFunc(func(ctx context.Context, tx *ent.Tx) error {
|
||||
// // Do some stuff before.
|
||||
// if err := next.Commit(ctx, tx); err != nil {
|
||||
// return err
|
||||
|
@ -95,7 +95,7 @@ func (tx *Tx) OnCommit(f CommitHook) {
|
|||
}
|
||||
|
||||
type (
|
||||
// Rollbacker is the interface that wraps the Rollbacker method.
|
||||
// Rollbacker is the interface that wraps the Rollback method.
|
||||
Rollbacker interface {
|
||||
Rollback(context.Context, *Tx) error
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ type (
|
|||
// and returns a Rollbacker. For example:
|
||||
//
|
||||
// hook := func(next ent.Rollbacker) ent.Rollbacker {
|
||||
// return ent.RollbackFunc(func(context.Context, tx *ent.Tx) error {
|
||||
// return ent.RollbackFunc(func(ctx context.Context, tx *ent.Tx) error {
|
||||
// // Do some stuff before.
|
||||
// if err := next.Rollback(ctx, tx); err != nil {
|
||||
// return err
|
||||
|
|
Loading…
Reference in a new issue