Add secmark/var + render blrules/conntrack/secmark/vars
- Add secmarks (id-keyed) and vars (key-keyed) resources: migration 0009, model, store CRUD, REST handlers. - Compiler rendering for the global-compiled tail: blrules, conntrack, secmarks render on enforcing devices; vars render on every device. This closes the rendering gap left by batch 1 (blrules/conntrack were stored but not rendered).
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
"git.unkin.net/unkin/tomswallapi/internal/model"
|
||||
)
|
||||
|
||||
// ---- Secmarks --------------------------------------------------------------
|
||||
|
||||
func (s *Store) ListSecmarks(ctx context.Context) ([]model.SecmarkRule, error) {
|
||||
rows, err := s.pool.Query(ctx,
|
||||
`SELECT id, secmark, chain, source, dest, proto, dport, sport, comment FROM secmarks ORDER BY id`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var out []model.SecmarkRule
|
||||
for rows.Next() {
|
||||
r, err := scanSecmark(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, r)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) GetSecmark(ctx context.Context, id int64) (model.SecmarkRule, error) {
|
||||
rows, err := s.pool.Query(ctx,
|
||||
`SELECT id, secmark, chain, source, dest, proto, dport, sport, comment FROM secmarks WHERE id = $1`, id)
|
||||
if err != nil {
|
||||
return model.SecmarkRule{}, err
|
||||
}
|
||||
defer rows.Close()
|
||||
if !rows.Next() {
|
||||
return model.SecmarkRule{}, ErrNotFound
|
||||
}
|
||||
return scanSecmark(rows)
|
||||
}
|
||||
|
||||
func scanSecmark(rows pgx.Rows) (model.SecmarkRule, error) {
|
||||
var r model.SecmarkRule
|
||||
var dport, sport []byte
|
||||
if err := rows.Scan(&r.ID, &r.Secmark, &r.Chain, &r.Source, &r.Dest, &r.Proto, &dport, &sport, &r.Comment); err != nil {
|
||||
return r, err
|
||||
}
|
||||
if err := unmarshalStrings(dport, &r.DPort); err != nil {
|
||||
return r, err
|
||||
}
|
||||
return r, unmarshalStrings(sport, &r.SPort)
|
||||
}
|
||||
|
||||
func (s *Store) CreateSecmark(ctx context.Context, r model.SecmarkRule) (int64, error) {
|
||||
dport, _ := jsonb(r.DPort)
|
||||
sport, _ := jsonb(r.SPort)
|
||||
var id int64
|
||||
err := pgx.BeginFunc(ctx, s.pool, func(tx pgx.Tx) error {
|
||||
if err := tx.QueryRow(ctx, `
|
||||
INSERT INTO secmarks (secmark, chain, source, dest, proto, dport, sport, comment)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING id`,
|
||||
r.Secmark, r.Chain, r.Source, r.Dest, r.Proto, dport, sport, r.Comment).Scan(&id); err != nil {
|
||||
return err
|
||||
}
|
||||
return bump(ctx, tx)
|
||||
})
|
||||
return id, err
|
||||
}
|
||||
|
||||
func (s *Store) DeleteSecmark(ctx context.Context, id int64) error {
|
||||
return s.deleteOne(ctx, `DELETE FROM secmarks WHERE id = $1`, id)
|
||||
}
|
||||
|
||||
// ---- Vars (key-keyed) ------------------------------------------------------
|
||||
|
||||
func (s *Store) ListVars(ctx context.Context) ([]model.Var, error) {
|
||||
rows, err := s.pool.Query(ctx, `SELECT key, value FROM vars ORDER BY key`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var out []model.Var
|
||||
for rows.Next() {
|
||||
var v model.Var
|
||||
if err := rows.Scan(&v.Key, &v.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, v)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) GetVar(ctx context.Context, key string) (model.Var, error) {
|
||||
var v model.Var
|
||||
err := s.pool.QueryRow(ctx, `SELECT key, value FROM vars WHERE key = $1`, key).Scan(&v.Key, &v.Value)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return v, ErrNotFound
|
||||
}
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (s *Store) UpsertVar(ctx context.Context, v model.Var) error {
|
||||
return pgx.BeginFunc(ctx, s.pool, func(tx pgx.Tx) error {
|
||||
if _, err := tx.Exec(ctx,
|
||||
`INSERT INTO vars (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value`,
|
||||
v.Key, v.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
return bump(ctx, tx)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) DeleteVar(ctx context.Context, key string) error {
|
||||
return s.deleteOne(ctx, `DELETE FROM vars WHERE key = $1`, key)
|
||||
}
|
||||
Reference in New Issue
Block a user