mirror of
https://github.com/gravitl/netmaker.git
synced 2026-04-22 16:07:11 +08:00
12cc967ba1
* fix(go): set persistent keep alive when registering host using sso; * fix(go): run posture check violations on delete; * fix(go): upsert node on approving pending host; * fix(go): resolve concurrency issues during group delete cleanup; * fix(go): update doc links; * fix(go): add created and updated fields to host; * fix(go): skip delete and update superadmin on sync users; * fix(go): use conn directly for now; * fix(go): remove acl for idp groups; * fix(go): quote fields; * fix(go): use filters with count; * feat(go): add a search query; * fix(go): cleanup acls; * fix(go): review fixes; * fix(go): remove additional loop; * fix(go): fix * v1.5.1: separate out idp sync and reset signals for HA * v1.5.1: add grps with name for logging * v1.5.1: clear posture check violations when all checks are deleted * v1.5.1: set static when default host * v1.5.1: fix db status check * rm set max conns * v1.5.1: reset auto assigned gw when disconnected * fix(go): skip global network admin and user groups when splitting; * v1.5.1: fix update node call from client * fix(go): separate out migration from normal usage; * fix(go): skip default groups; * fix(go): create policies for existing groups on network create; * fix(go): skip fatal log on clickhouse conn; * fix(go): add posture check cleanup; --------- Co-authored-by: VishalDalwadi <dalwadivishal26@gmail.com> Co-authored-by: Vishal Dalwadi <51291657+VishalDalwadi@users.noreply.github.com>
204 lines
6.5 KiB
Go
204 lines
6.5 KiB
Go
package schema
|
|
|
|
import (
|
|
"context"
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gravitl/netmaker/db"
|
|
dbtypes "github.com/gravitl/netmaker/db/types"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
"gorm.io/datatypes"
|
|
)
|
|
|
|
// Iface struct for local interfaces of a node
|
|
type Iface struct {
|
|
Name string `json:"name"`
|
|
Address net.IPNet `json:"address"`
|
|
AddressString string `json:"addressString"`
|
|
}
|
|
|
|
type WgKey struct {
|
|
wgtypes.Key
|
|
}
|
|
|
|
func (k WgKey) Value() (driver.Value, error) {
|
|
return k.Key.String(), nil
|
|
}
|
|
|
|
func (k *WgKey) Scan(value interface{}) error {
|
|
str, ok := value.(string)
|
|
if !ok {
|
|
return fmt.Errorf("expected string for WgKey, got %T", value)
|
|
}
|
|
key, err := wgtypes.ParseKey(str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
k.Key = key
|
|
return nil
|
|
}
|
|
|
|
func (k WgKey) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(k.Key)
|
|
}
|
|
|
|
func (k *WgKey) UnmarshalJSON(data []byte) error {
|
|
var key wgtypes.Key
|
|
err := json.Unmarshal(data, &key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
k.Key = key
|
|
return nil
|
|
}
|
|
|
|
type AddrPort struct {
|
|
netip.AddrPort
|
|
}
|
|
|
|
func (a AddrPort) Value() (driver.Value, error) {
|
|
if !a.IsValid() {
|
|
return nil, nil
|
|
}
|
|
return a.String(), nil
|
|
}
|
|
|
|
func (a *AddrPort) Scan(value interface{}) error {
|
|
if value == nil {
|
|
return nil
|
|
}
|
|
str, ok := value.(string)
|
|
if !ok {
|
|
return fmt.Errorf("expected string for AddrPort, got %T", value)
|
|
}
|
|
ap, err := netip.ParseAddrPort(str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
a.AddrPort = ap
|
|
return nil
|
|
}
|
|
|
|
func (a AddrPort) MarshalJSON() ([]byte, error) {
|
|
if !a.IsValid() {
|
|
return json.Marshal(nil)
|
|
}
|
|
return json.Marshal(a.String())
|
|
}
|
|
|
|
func (a *AddrPort) UnmarshalJSON(data []byte) error {
|
|
var s *string
|
|
if err := json.Unmarshal(data, &s); err != nil {
|
|
return err
|
|
}
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
ap, err := netip.ParseAddrPort(*s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
a.AddrPort = ap
|
|
return nil
|
|
}
|
|
|
|
type Host struct {
|
|
ID uuid.UUID `gorm:"primaryKey" json:"id" yaml:"id"`
|
|
Verbosity int `json:"verbosity" yaml:"verbosity"`
|
|
FirewallInUse string `json:"firewallinuse" yaml:"firewallinuse"`
|
|
Version string `json:"version" yaml:"version"`
|
|
IPForwarding bool `json:"ipforwarding" yaml:"ipforwarding"`
|
|
DaemonInstalled bool `json:"daemoninstalled" yaml:"daemoninstalled"`
|
|
AutoUpdate bool `json:"autoupdate" yaml:"autoupdate"`
|
|
HostPass string `json:"hostpass" yaml:"hostpass"`
|
|
Name string `json:"name" yaml:"name"`
|
|
OS string `json:"os" yaml:"os"`
|
|
OSFamily string `json:"os_family" yaml:"os_family"`
|
|
OSVersion string `json:"os_version" yaml:"os_version"`
|
|
KernelVersion string `json:"kernel_version" yaml:"kernel_version"`
|
|
Interface string `json:"interface" yaml:"interface"`
|
|
Debug bool `json:"debug" yaml:"debug"`
|
|
ListenPort int `json:"listenport" yaml:"listenport"`
|
|
WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"`
|
|
MTU int `json:"mtu" yaml:"mtu"`
|
|
PublicKey WgKey `json:"publickey" yaml:"publickey"`
|
|
MacAddress net.HardwareAddr `json:"macaddress" yaml:"macaddress"`
|
|
TrafficKeyPublic datatypes.JSONSlice[byte] `json:"traffickeypublic" yaml:"traffickeypublic"`
|
|
Nodes datatypes.JSONSlice[string] `json:"nodes" yaml:"nodes"`
|
|
Interfaces datatypes.JSONSlice[Iface] `json:"interfaces" yaml:"interfaces"`
|
|
DefaultInterface string `json:"defaultinterface" yaml:"defaultinterface"`
|
|
EndpointIP net.IP `json:"endpointip" yaml:"endpointip"`
|
|
EndpointIPv6 net.IP `json:"endpointipv6" yaml:"endpointipv6"`
|
|
IsDocker bool `json:"isdocker" yaml:"isdocker"`
|
|
IsK8S bool `json:"isk8s" yaml:"isk8s"`
|
|
IsStaticPort bool `json:"isstaticport" yaml:"isstaticport"`
|
|
IsStatic bool `json:"isstatic" yaml:"isstatic"`
|
|
IsDefault bool `json:"isdefault" yaml:"isdefault"`
|
|
DNS string `json:"dns_status" yaml:"dns_status"`
|
|
NatType string `json:"nat_type,omitempty" yaml:"nat_type,omitempty"`
|
|
TurnEndpoint *AddrPort `json:"turn_endpoint,omitempty" yaml:"turn_endpoint,omitempty"`
|
|
PersistentKeepalive time.Duration `json:"persistentkeepalive" swaggertype:"primitive,integer" format:"int64" yaml:"persistentkeepalive"`
|
|
Location string `json:"location" yaml:"location"` // Format: "lat,lon"
|
|
CountryCode string `json:"country_code" yaml:"country_code"`
|
|
EnableFlowLogs bool `json:"enable_flow_logs" yaml:"enable_flow_logs"`
|
|
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" yaml:"updated_at"`
|
|
}
|
|
|
|
func (h *Host) TableName() string {
|
|
return "hosts_v1"
|
|
}
|
|
|
|
func (h *Host) Create(ctx context.Context) error {
|
|
return db.FromContext(ctx).Model(&Host{}).Create(h).Error
|
|
}
|
|
|
|
func (h *Host) Get(ctx context.Context) error {
|
|
return db.FromContext(ctx).Model(&Host{}).
|
|
Where("id = ?", h.ID).
|
|
First(h).
|
|
Error
|
|
}
|
|
|
|
func (h *Host) Count(ctx context.Context, options ...dbtypes.Option) (int, error) {
|
|
var count int64
|
|
query := db.FromContext(ctx).Model(&Host{})
|
|
|
|
for _, option := range options {
|
|
query = option(query)
|
|
}
|
|
|
|
err := query.Count(&count).Error
|
|
return int(count), err
|
|
}
|
|
|
|
func (h *Host) ListAll(ctx context.Context, options ...dbtypes.Option) ([]Host, error) {
|
|
var hosts []Host
|
|
query := db.FromContext(ctx).Model(&Host{})
|
|
|
|
for _, option := range options {
|
|
query = option(query)
|
|
}
|
|
|
|
err := query.Find(&hosts).Error
|
|
return hosts, err
|
|
}
|
|
|
|
func (h *Host) Upsert(ctx context.Context) error {
|
|
return db.FromContext(ctx).Save(h).Error
|
|
}
|
|
|
|
func (h *Host) Delete(ctx context.Context) error {
|
|
return db.FromContext(ctx).Model(&Host{}).
|
|
Where("id = ?", h.ID).
|
|
Delete(h).
|
|
Error
|
|
}
|