2024-09-14 04:21:14 +00:00
|
|
|
package reservation
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"log/slog"
|
|
|
|
|
|
|
|
"git.staur.ca/stobbsm/kea-manage/lib/types"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
|
|
)
|
|
|
|
|
|
|
|
const insertHostReservation = `INSERT INTO hosts (dhcp_identifier,
|
|
|
|
dhcp_identifier_type,
|
|
|
|
dhcp4_subnet_id,
|
|
|
|
ipv4_address,
|
|
|
|
hostname)
|
|
|
|
VALUES (DECODE(REPLACE($1, ':', ''), 'hex'), $2, $3, (SELECT ($4::inet - '0.0.0.0'::inet)), $5);`
|
|
|
|
|
|
|
|
const getHostIDWithMacAddr = `SELECT host_id
|
|
|
|
FROM hosts
|
|
|
|
WHERE dhcp4_subnet_id = $1
|
|
|
|
AND dhcp_identifier_type = $2
|
|
|
|
AND dhcp_identifier = (DECODE(REPLACE($3, ':', ''), 'hex'));`
|
|
|
|
|
|
|
|
const insertIfNotExists = `INSERT INTO hosts (dhcp_identifier,
|
|
|
|
dhcp_identifier_type,
|
|
|
|
dhcp4_subnet_id,
|
|
|
|
ipv4_address,
|
|
|
|
hostname)
|
|
|
|
SELECT DECODE(REPLACE($1, ':', ''), 'hex'), $2, $3, (SELECT ($4::inet - '0.0.0.0'::inet)), $5
|
|
|
|
WHERE NOT EXISTS (
|
|
|
|
SELECT host_id FROM hosts
|
|
|
|
WHERE dhcp4_subnet_id = $3
|
|
|
|
AND dhcp_identifier_type = $2
|
|
|
|
AND dhcp_identifier = DECODE(REPLACE($1, ':', ''), 'hex'));`
|
|
|
|
|
|
|
|
type ReservationV4 struct {
|
|
|
|
Type int
|
|
|
|
SubnetID int
|
2024-09-20 15:21:18 +00:00
|
|
|
MacAddr string
|
2024-09-14 04:21:14 +00:00
|
|
|
Ipv4 string
|
|
|
|
Hostname string
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReserveV4MacAddr(mac string, addr string, hostname string, subnet int) *ReservationV4 {
|
|
|
|
r := &ReservationV4{
|
|
|
|
MacAddr: mac,
|
|
|
|
Type: int(types.MacAddress),
|
|
|
|
SubnetID: subnet,
|
|
|
|
Ipv4: addr,
|
|
|
|
Hostname: hostname,
|
|
|
|
}
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReservationV4) check(conn *pgx.Conn) error {
|
|
|
|
rows, err := conn.Query(context.Background(), getHostIDWithMacAddr, r.SubnetID, r.Type, r.MacAddr)
|
|
|
|
if err != nil {
|
|
|
|
slog.Error("error during check query")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
slog.Info("check result size")
|
|
|
|
if rv, _ := rows.Values(); len(rv) > 0 {
|
|
|
|
return errors.New("existing record found")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReservationV4) Insert(conn *pgx.Conn) error {
|
|
|
|
tx, err := conn.Begin(context.Background())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer tx.Rollback(context.Background())
|
|
|
|
|
|
|
|
if _, err = tx.Exec(context.Background(), insertIfNotExists, r.MacAddr, r.Type, r.SubnetID, r.Ipv4, r.Hostname); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = tx.Commit(context.Background()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|