Skip to content

Commit

Permalink
db: don't set bouncer last_pull until first connection
Browse files Browse the repository at this point in the history
  • Loading branch information
mmetc committed May 31, 2024
1 parent c1e858c commit d7d7d46
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 32 deletions.
7 changes: 6 additions & 1 deletion cmd/crowdsec-cli/bouncers.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ func (cli *cliBouncers) list() error {
valid = "pending"
}

if err := csvwriter.Write([]string{b.Name, b.IPAddress, valid, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType}); err != nil {
lastPull := ""
if b.LastPull != nil {
lastPull = b.LastPull.Format(time.RFC3339)
}

Check warning on line 122 in cmd/crowdsec-cli/bouncers.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/bouncers.go#L121-L122

Added lines #L121 - L122 were not covered by tests

if err := csvwriter.Write([]string{b.Name, b.IPAddress, valid, lastPull, b.Type, b.Version, b.AuthType}); err != nil {
return fmt.Errorf("failed to write raw: %w", err)
}
}
Expand Down
7 changes: 6 additions & 1 deletion cmd/crowdsec-cli/bouncers_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ func getBouncersTable(out io.Writer, bouncers []*ent.Bouncer) {
revoked = emoji.Prohibited
}

t.AddRow(b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType)
lastPull := ""
if b.LastPull != nil {
lastPull = b.LastPull.Format(time.RFC3339)
}

Check warning on line 27 in cmd/crowdsec-cli/bouncers_table.go

View check run for this annotation

Codecov / codecov/patch

cmd/crowdsec-cli/bouncers_table.go#L26-L27

Added lines #L26 - L27 were not covered by tests

t.AddRow(b.Name, b.IPAddress, revoked, lastPull, b.Type, b.Version, b.AuthType)
}

t.Render()
Expand Down
11 changes: 8 additions & 3 deletions pkg/apiserver/controllers/v1/decisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (c *Controller) GetDecision(gctx *gin.Context) {
return
}

if time.Now().UTC().Sub(bouncerInfo.LastPull) >= time.Minute {
if bouncerInfo.LastPull == nil || time.Now().UTC().Sub(*bouncerInfo.LastPull) >= time.Minute {
if err := c.DBClient.UpdateBouncerLastPull(time.Now().UTC(), bouncerInfo.ID); err != nil {
log.Errorf("failed to update bouncer last pull: %v", err)
}
Expand Down Expand Up @@ -186,7 +186,7 @@ func writeStartupDecisions(gctx *gin.Context, filters map[string][]string, dbFun
return nil
}

func writeDeltaDecisions(gctx *gin.Context, filters map[string][]string, lastPull time.Time, dbFunc func(time.Time, map[string][]string) ([]*ent.Decision, error)) error {
func writeDeltaDecisions(gctx *gin.Context, filters map[string][]string, lastPull *time.Time, dbFunc func(*time.Time, map[string][]string) ([]*ent.Decision, error)) error {

Check warning on line 189 in pkg/apiserver/controllers/v1/decisions.go

View check run for this annotation

Codecov / codecov/patch

pkg/apiserver/controllers/v1/decisions.go#L189

Added line #L189 was not covered by tests
//respBuffer := bytes.NewBuffer([]byte{})
limit := 30000 //FIXME : make it configurable
needComma := false
Expand Down Expand Up @@ -348,8 +348,13 @@ func (c *Controller) StreamDecisionNonChunked(gctx *gin.Context, bouncerInfo *en
//data = KeepLongestDecision(data)
ret["new"] = FormatDecisions(data)

since := time.Time{}
if bouncerInfo.LastPull != nil {
since = bouncerInfo.LastPull.Add(-2 * time.Second)
}

Check warning on line 354 in pkg/apiserver/controllers/v1/decisions.go

View check run for this annotation

Codecov / codecov/patch

pkg/apiserver/controllers/v1/decisions.go#L354

Added line #L354 was not covered by tests

// getting expired decisions
data, err = c.DBClient.QueryExpiredDecisionsSinceWithFilters(bouncerInfo.LastPull.Add((-2 * time.Second)), filters) // do we want to give exactly lastPull time ?
data, err = c.DBClient.QueryExpiredDecisionsSinceWithFilters(&since, filters) // do we want to give exactly lastPull time ?
if err != nil {
log.Errorf("unable to query expired decision for '%s' : %v", bouncerInfo.Name, err)
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
Expand Down
15 changes: 11 additions & 4 deletions pkg/database/decisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,15 @@ func longestDecisionForScopeTypeValue(s *sql.Selector) {
)
}

func (c *Client) QueryExpiredDecisionsSinceWithFilters(since time.Time, filters map[string][]string) ([]*ent.Decision, error) {
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()),
decision.UntilGT(since),
)

Check warning on line 255 in pkg/database/decisions.go

View check run for this annotation

Codecov / codecov/patch

pkg/database/decisions.go#L255

Added line #L255 was not covered by tests
if since != nil {
query = query.Where(decision.UntilGT(*since))
}

Check warning on line 258 in pkg/database/decisions.go

View check run for this annotation

Codecov / codecov/patch

pkg/database/decisions.go#L258

Added line #L258 was not covered by tests

//Allow a bouncer to ask for non-deduplicated results
if v, ok := filters["dedup"]; !ok || v[0] != "false" {
query = query.Where(longestDecisionForScopeTypeValue)
Expand All @@ -274,12 +278,15 @@ func (c *Client) QueryExpiredDecisionsSinceWithFilters(since time.Time, filters
return data, nil
}

func (c *Client) QueryNewDecisionsSinceWithFilters(since time.Time, filters map[string][]string) ([]*ent.Decision, error) {
func (c *Client) QueryNewDecisionsSinceWithFilters(since *time.Time, filters map[string][]string) ([]*ent.Decision, error) {
query := c.Ent.Decision.Query().Where(
decision.CreatedAtGT(since),
decision.UntilGT(time.Now().UTC()),
)

if since != nil {
query = query.Where(decision.CreatedAtGT(*since))
}

Check warning on line 288 in pkg/database/decisions.go

View check run for this annotation

Codecov / codecov/patch

pkg/database/decisions.go#L288

Added line #L288 was not covered by tests

// Allow a bouncer to ask for non-deduplicated results
if v, ok := filters["dedup"]; !ok || v[0] != "false" {
query = query.Where(longestDecisionForScopeTypeValue)
Expand Down
11 changes: 7 additions & 4 deletions pkg/database/ent/bouncer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pkg/database/ent/bouncer/bouncer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions pkg/database/ent/bouncer/where.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 1 addition & 8 deletions pkg/database/ent/bouncer_create.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions pkg/database/ent/bouncer_update.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/database/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion pkg/database/ent/mutation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions pkg/database/ent/runtime.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions pkg/database/ent/schema/bouncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ func (Bouncer) Fields() []ent.Field {
field.String("ip_address").Default("").Optional().StructTag(`json:"ip_address"`),
field.String("type").Optional().StructTag(`json:"type"`),
field.String("version").Optional().StructTag(`json:"version"`),
field.Time("last_pull").
Default(types.UtcNow).StructTag(`json:"last_pull"`),
field.Time("last_pull").Nillable().Optional().StructTag(`json:"last_pull"`),
field.String("auth_type").StructTag(`json:"auth_type"`).Default(types.ApiKeyAuthType),
}
}
Expand Down
15 changes: 14 additions & 1 deletion test/bats/10_bouncers.bats
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,20 @@ teardown() {
assert_output --partial "API key for 'ciTestBouncer':"
rune -0 cscli bouncers delete ciTestBouncer
rune -0 cscli bouncers list -o json
assert_output '[]'
assert_json '[]'
}

@test "cscli bouncers list" {
rune -0 cscli bouncers add ciTestBouncer
rune -0 cscli bouncers list -o json
rune -0 jq -c '.[] | [.ip_address,.last_pull,.name]' <(output)
assert_json '["",null,"ciTestBouncer"]'
rune -0 cscli bouncers list -o raw
assert_line 'name,ip,revoked,last_pull,type,version,auth_type'
assert_line 'ciTestBouncer,,validated,,,,api-key'
rune -0 cscli bouncers list -o human
assert_output --regexp 'ciTestBouncer.*api-key.*'
# TODO: connect and list again
}

@test "we can create a bouncer with a known key" {
Expand Down

0 comments on commit d7d7d46

Please sign in to comment.