package wireguard import ( "context" "errors" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "git.netcell-it.de/projekte/edgeguard-native/internal/models" ) var ErrIfaceNotFound = errors.New("wireguard interface not found") type InterfacesRepo struct { Pool *pgxpool.Pool } func NewInterfacesRepo(pool *pgxpool.Pool) *InterfacesRepo { return &InterfacesRepo{Pool: pool} } const ifaceBaseSelect = ` SELECT id, name, mode, address_cidr, listen_port, public_key, private_key_enc, peer_endpoint, peer_public_key, peer_psk_enc, allowed_ips, persistent_keepalive, mtu, role, active, description, created_at, updated_at FROM wireguard_interfaces ` func (r *InterfacesRepo) List(ctx context.Context) ([]models.WireguardInterface, error) { rows, err := r.Pool.Query(ctx, ifaceBaseSelect+" ORDER BY name ASC") if err != nil { return nil, err } defer rows.Close() out := make([]models.WireguardInterface, 0, 4) for rows.Next() { i, err := scanIface(rows) if err != nil { return nil, err } out = append(out, *i) } return out, rows.Err() } func (r *InterfacesRepo) Get(ctx context.Context, id int64) (*models.WireguardInterface, error) { row := r.Pool.QueryRow(ctx, ifaceBaseSelect+" WHERE id = $1", id) i, err := scanIface(row) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, ErrIfaceNotFound } return nil, err } return i, nil } func (r *InterfacesRepo) Create(ctx context.Context, i models.WireguardInterface) (*models.WireguardInterface, error) { row := r.Pool.QueryRow(ctx, ` INSERT INTO wireguard_interfaces ( name, mode, address_cidr, listen_port, public_key, private_key_enc, peer_endpoint, peer_public_key, peer_psk_enc, allowed_ips, persistent_keepalive, mtu, role, active, description ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING id, name, mode, address_cidr, listen_port, public_key, private_key_enc, peer_endpoint, peer_public_key, peer_psk_enc, allowed_ips, persistent_keepalive, mtu, role, active, description, created_at, updated_at`, i.Name, i.Mode, i.AddressCIDR, i.ListenPort, i.PublicKey, i.PrivateKeyEnc, i.PeerEndpoint, i.PeerPublicKey, i.PeerPSKEnc, i.AllowedIPs, i.PersistentKeepalive, i.MTU, i.Role, i.Active, i.Description) return scanIface(row) } func (r *InterfacesRepo) Update(ctx context.Context, id int64, i models.WireguardInterface) (*models.WireguardInterface, error) { row := r.Pool.QueryRow(ctx, ` UPDATE wireguard_interfaces SET name = $1, mode = $2, address_cidr = $3, listen_port = $4, public_key = $5, private_key_enc = $6, peer_endpoint = $7, peer_public_key = $8, peer_psk_enc = $9, allowed_ips = $10, persistent_keepalive = $11, mtu = $12, role = $13, active = $14, description = $15, updated_at = NOW() WHERE id = $16 RETURNING id, name, mode, address_cidr, listen_port, public_key, private_key_enc, peer_endpoint, peer_public_key, peer_psk_enc, allowed_ips, persistent_keepalive, mtu, role, active, description, created_at, updated_at`, i.Name, i.Mode, i.AddressCIDR, i.ListenPort, i.PublicKey, i.PrivateKeyEnc, i.PeerEndpoint, i.PeerPublicKey, i.PeerPSKEnc, i.AllowedIPs, i.PersistentKeepalive, i.MTU, i.Role, i.Active, i.Description, id) out, err := scanIface(row) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, ErrIfaceNotFound } return nil, err } return out, nil } func (r *InterfacesRepo) Delete(ctx context.Context, id int64) error { tag, err := r.Pool.Exec(ctx, `DELETE FROM wireguard_interfaces WHERE id = $1`, id) if err != nil { return err } if tag.RowsAffected() == 0 { return ErrIfaceNotFound } return nil } func scanIface(row interface{ Scan(...any) error }) (*models.WireguardInterface, error) { var i models.WireguardInterface if err := row.Scan( &i.ID, &i.Name, &i.Mode, &i.AddressCIDR, &i.ListenPort, &i.PublicKey, &i.PrivateKeyEnc, &i.PeerEndpoint, &i.PeerPublicKey, &i.PeerPSKEnc, &i.AllowedIPs, &i.PersistentKeepalive, &i.MTU, &i.Role, &i.Active, &i.Description, &i.CreatedAt, &i.UpdatedAt, ); err != nil { return nil, err } return &i, nil }