Use Config Manager

This commit is contained in:
Samuel Lorch 2023-04-01 18:17:48 +02:00
parent 081aeec142
commit 70d69f04cf
11 changed files with 55 additions and 104 deletions

View file

@ -12,6 +12,6 @@ type GetDestinationNATRulesResult struct {
func (f *Firewall) GetDestinationNATRules(ctx context.Context, params struct{}) (GetDestinationNATRulesResult, error) { func (f *Firewall) GetDestinationNATRules(ctx context.Context, params struct{}) (GetDestinationNATRulesResult, error) {
return GetDestinationNATRulesResult{ return GetDestinationNATRulesResult{
DestinationNATRules: f.Conf.Firewall.DestinationNATRules, DestinationNATRules: f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules,
}, nil }, nil
} }

View file

@ -1,9 +1,9 @@
package firewall package firewall
import ( import (
"nfsense.net/nfsense/internal/definitions" "nfsense.net/nfsense/internal/config"
) )
type Firewall struct { type Firewall struct {
Conf *definitions.Config ConfigManager *config.ConfigManager
} }

View file

@ -12,6 +12,6 @@ type GetForwardRulesResult struct {
func (f *Firewall) GetForwardRules(ctx context.Context, params struct{}) (GetForwardRulesResult, error) { func (f *Firewall) GetForwardRules(ctx context.Context, params struct{}) (GetForwardRulesResult, error) {
return GetForwardRulesResult{ return GetForwardRulesResult{
ForwardRules: f.Conf.Firewall.ForwardRules, ForwardRules: f.ConfigManager.GetPendingConfig().Firewall.ForwardRules,
}, nil }, nil
} }

View file

@ -12,6 +12,6 @@ type GetSourceNATRulesResult struct {
func (f *Firewall) GetSourceNATRules(ctx context.Context, params struct{}) (GetSourceNATRulesResult, error) { func (f *Firewall) GetSourceNATRules(ctx context.Context, params struct{}) (GetSourceNATRulesResult, error) {
return GetSourceNATRulesResult{ return GetSourceNATRulesResult{
SourceNATRules: f.Conf.Firewall.SourceNATRules, SourceNATRules: f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules,
}, nil }, nil
} }

View file

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"nfsense.net/nfsense/internal/definitions" "nfsense.net/nfsense/internal/definitions"
"nfsense.net/nfsense/internal/interfaces"
) )
type GetInterfacesResult struct { type GetInterfacesResult struct {
@ -14,7 +13,7 @@ type GetInterfacesResult struct {
func (f *Network) GetInterfaces(ctx context.Context, params struct{}) (GetInterfacesResult, error) { func (f *Network) GetInterfaces(ctx context.Context, params struct{}) (GetInterfacesResult, error) {
return GetInterfacesResult{ return GetInterfacesResult{
Interfaces: f.Conf.Network.Interfaces, Interfaces: f.ConfigManager.GetPendingConfig().Network.Interfaces,
}, nil }, nil
} }
@ -24,12 +23,12 @@ type CreateInterfaceParameters struct {
} }
func (f *Network) CreateInterface(ctx context.Context, params CreateInterfaceParameters) (struct{}, error) { func (f *Network) CreateInterface(ctx context.Context, params CreateInterfaceParameters) (struct{}, error) {
_, ok := f.Conf.Network.Interfaces[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name]
if ok { if ok {
return struct{}{}, fmt.Errorf("Interface already Exists") return struct{}{}, fmt.Errorf("Interface already Exists")
} }
f.Conf.Network.Interfaces[params.Name] = params.Interface f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name] = params.Interface
return struct{}{}, nil return struct{}{}, nil
} }
@ -39,12 +38,12 @@ type UpdateInterfaceParameters struct {
} }
func (f *Network) UpdateInterface(ctx context.Context, params CreateInterfaceParameters) (struct{}, error) { func (f *Network) UpdateInterface(ctx context.Context, params CreateInterfaceParameters) (struct{}, error) {
_, ok := f.Conf.Network.Interfaces[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name]
if !ok { if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist") return struct{}{}, fmt.Errorf("Interface does not Exist")
} }
f.Conf.Network.Interfaces[params.Name] = params.Interface f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name] = params.Interface
return struct{}{}, nil return struct{}{}, nil
} }
@ -53,29 +52,11 @@ type DeleteInterfaceParameters struct {
} }
func (f *Network) DeleteInterface(ctx context.Context, params DeleteInterfaceParameters) (struct{}, error) { func (f *Network) DeleteInterface(ctx context.Context, params DeleteInterfaceParameters) (struct{}, error) {
_, ok := f.Conf.Network.Interfaces[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name]
if !ok { if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist") return struct{}{}, fmt.Errorf("Interface does not Exist")
} }
delete(f.Conf.Network.Interfaces, params.Name) delete(f.ConfigManager.GetPendingConfig().Network.Interfaces, params.Name)
return struct{}{}, nil return struct{}{}, nil
} }
type ApplyInterfacesResult struct {
Log string
}
func (f *Network) ApplyInterfaces(ctx context.Context, params struct{}) (ApplyInterfacesResult, error) {
data, err := interfaces.GenerateInterfacesFile(*f.Conf)
if err != nil {
return ApplyInterfacesResult{}, fmt.Errorf("Generating Interfaces File: %w", err)
}
log, err := interfaces.ApplyInterfacesFile(data)
if err != nil {
return ApplyInterfacesResult{}, fmt.Errorf("Applying Interfaces File: %w", err)
}
return ApplyInterfacesResult{
Log: log,
}, nil
}

View file

@ -1,9 +1,7 @@
package network package network
import ( import "nfsense.net/nfsense/internal/config"
"nfsense.net/nfsense/internal/definitions"
)
type Network struct { type Network struct {
Conf *definitions.Config ConfigManager *config.ConfigManager
} }

View file

@ -13,7 +13,7 @@ type GetAddressesResult struct {
func (f *Object) GetAddresses(ctx context.Context, params struct{}) (GetAddressesResult, error) { func (f *Object) GetAddresses(ctx context.Context, params struct{}) (GetAddressesResult, error) {
return GetAddressesResult{ return GetAddressesResult{
Addresses: f.Conf.Object.Addresses, Addresses: f.ConfigManager.GetPendingConfig().Object.Addresses,
}, nil }, nil
} }
@ -23,12 +23,12 @@ type CreateAddressParameters struct {
} }
func (f *Object) CreateAddress(ctx context.Context, params CreateAddressParameters) (struct{}, error) { func (f *Object) CreateAddress(ctx context.Context, params CreateAddressParameters) (struct{}, error) {
_, ok := f.Conf.Object.Addresses[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name]
if ok { if ok {
return struct{}{}, fmt.Errorf("Address already Exists") return struct{}{}, fmt.Errorf("Address already Exists")
} }
f.Conf.Object.Addresses[params.Name] = params.Address f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name] = params.Address
return struct{}{}, nil return struct{}{}, nil
} }
@ -38,12 +38,12 @@ type UpdateAddressParameters struct {
} }
func (f *Object) UpdateAddress(ctx context.Context, params CreateAddressParameters) (struct{}, error) { func (f *Object) UpdateAddress(ctx context.Context, params CreateAddressParameters) (struct{}, error) {
_, ok := f.Conf.Object.Addresses[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name]
if !ok { if !ok {
return struct{}{}, fmt.Errorf("Address does not Exist") return struct{}{}, fmt.Errorf("Address does not Exist")
} }
f.Conf.Object.Addresses[params.Name] = params.Address f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name] = params.Address
return struct{}{}, nil return struct{}{}, nil
} }
@ -52,11 +52,11 @@ type DeleteAddressParameters struct {
} }
func (f *Object) DeleteAddress(ctx context.Context, params DeleteAddressParameters) (struct{}, error) { func (f *Object) DeleteAddress(ctx context.Context, params DeleteAddressParameters) (struct{}, error) {
_, ok := f.Conf.Object.Addresses[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name]
if !ok { if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist") return struct{}{}, fmt.Errorf("Interface does not Exist")
} }
delete(f.Conf.Object.Addresses, params.Name) delete(f.ConfigManager.GetPendingConfig().Object.Addresses, params.Name)
return struct{}{}, nil return struct{}{}, nil
} }

View file

@ -1,7 +1,7 @@
package object package object
import "nfsense.net/nfsense/internal/definitions" import "nfsense.net/nfsense/internal/config"
type Object struct { type Object struct {
Conf *definitions.Config ConfigManager *config.ConfigManager
} }

View file

@ -13,7 +13,7 @@ type GetServicesResult struct {
func (f *Object) GetServices(ctx context.Context, params struct{}) (GetServicesResult, error) { func (f *Object) GetServices(ctx context.Context, params struct{}) (GetServicesResult, error) {
return GetServicesResult{ return GetServicesResult{
Services: f.Conf.Object.Services, Services: f.ConfigManager.GetPendingConfig().Object.Services,
}, nil }, nil
} }
@ -23,12 +23,12 @@ type CreateServiceParameters struct {
} }
func (f *Object) CreateService(ctx context.Context, params CreateServiceParameters) (struct{}, error) { func (f *Object) CreateService(ctx context.Context, params CreateServiceParameters) (struct{}, error) {
_, ok := f.Conf.Object.Services[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.Name]
if ok { if ok {
return struct{}{}, fmt.Errorf("Service already Exists") return struct{}{}, fmt.Errorf("Service already Exists")
} }
f.Conf.Object.Services[params.Name] = params.Service f.ConfigManager.GetPendingConfig().Object.Services[params.Name] = params.Service
return struct{}{}, nil return struct{}{}, nil
} }
@ -38,12 +38,12 @@ type UpdateServiceParameters struct {
} }
func (f *Object) UpdateService(ctx context.Context, params CreateServiceParameters) (struct{}, error) { func (f *Object) UpdateService(ctx context.Context, params CreateServiceParameters) (struct{}, error) {
_, ok := f.Conf.Object.Services[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.Name]
if !ok { if !ok {
return struct{}{}, fmt.Errorf("Service does not Exist") return struct{}{}, fmt.Errorf("Service does not Exist")
} }
f.Conf.Object.Services[params.Name] = params.Service f.ConfigManager.GetPendingConfig().Object.Services[params.Name] = params.Service
return struct{}{}, nil return struct{}{}, nil
} }
@ -52,11 +52,11 @@ type DeleteServiceParameters struct {
} }
func (f *Object) DeleteService(ctx context.Context, params DeleteServiceParameters) (struct{}, error) { func (f *Object) DeleteService(ctx context.Context, params DeleteServiceParameters) (struct{}, error) {
_, ok := f.Conf.Object.Services[params.Name] _, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.Name]
if !ok { if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist") return struct{}{}, fmt.Errorf("Interface does not Exist")
} }
delete(f.Conf.Object.Services, params.Name) delete(f.ConfigManager.GetPendingConfig().Object.Services, params.Name)
return struct{}{}, nil return struct{}{}, nil
} }

View file

@ -8,7 +8,7 @@ import (
"golang.org/x/exp/slog" "golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/definitions" "nfsense.net/nfsense/internal/config"
"nfsense.net/nfsense/internal/jsonrpc" "nfsense.net/nfsense/internal/jsonrpc"
"nfsense.net/nfsense/internal/session" "nfsense.net/nfsense/internal/session"
) )
@ -18,7 +18,7 @@ var mux = http.NewServeMux()
var apiHandler *jsonrpc.Handler var apiHandler *jsonrpc.Handler
var stopCleanup chan struct{} var stopCleanup chan struct{}
func StartWebserver(conf *definitions.Config, _apiHandler *jsonrpc.Handler) { func StartWebserver(configManager *config.ConfigManager, _apiHandler *jsonrpc.Handler) {
server.Addr = ":8080" server.Addr = ":8080"
server.Handler = mux server.Handler = mux
apiHandler = _apiHandler apiHandler = _apiHandler

74
main.go
View file

@ -2,21 +2,19 @@ package main
import ( import (
"context" "context"
"encoding/json"
"flag" "flag"
"fmt"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"time" "time"
"golang.org/x/exp/slog" "golang.org/x/exp/slog"
configAPI "nfsense.net/nfsense/internal/api/config"
"nfsense.net/nfsense/internal/api/firewall" "nfsense.net/nfsense/internal/api/firewall"
"nfsense.net/nfsense/internal/api/network" "nfsense.net/nfsense/internal/api/network"
"nfsense.net/nfsense/internal/api/object" "nfsense.net/nfsense/internal/api/object"
"nfsense.net/nfsense/internal/definitions" "nfsense.net/nfsense/internal/config"
"nfsense.net/nfsense/internal/jsonrpc" "nfsense.net/nfsense/internal/jsonrpc"
"nfsense.net/nfsense/internal/nftables"
"nfsense.net/nfsense/internal/server" "nfsense.net/nfsense/internal/server"
) )
@ -26,27 +24,31 @@ func main() {
slog.Info("Starting...") slog.Info("Starting...")
conf, err := LoadConfiguration("config.json") configManager := config.CreateConfigManager()
err := configManager.LoadCurrentConfigFromDisk()
if err != nil { if err != nil {
slog.Error("Loading Config", err) slog.Error("Loading Current Config", err)
os.Exit(1) os.Exit(1)
} }
slog.Info("Config Loaded", "config", conf) slog.Info("Config Loaded")
err = definitions.ValidateConfig(conf) err = configManager.LoadPendingConfigFromDisk()
if err != nil { if err != nil {
slog.Error("Validating Config", err) slog.Error("Loading Pending Config", err)
os.Exit(1) err = configManager.DiscardPendingConfig()
if err != nil {
slog.Error("Discarding Pending Config", err)
os.Exit(1)
}
} }
slog.Info("Validating Config...")
if *applyPtr { if *applyPtr {
slog.Info("Applying Config...") slog.Info("Applying Config...")
err := apply(conf) err := configManager.ApplyPendingChanges()
if err != nil { if err != nil {
slog.Error("Applying Config", err) slog.Error("Applying Pending Config", err)
os.Exit(1) os.Exit(1)
} }
slog.Info("Config Applied, Exiting...") slog.Info("Config Applied, Exiting...")
@ -55,10 +57,10 @@ func main() {
slog.Info("Setup API...") slog.Info("Setup API...")
apiHandler := jsonrpc.NewHandler(100 << 20) apiHandler := jsonrpc.NewHandler(100 << 20)
RegisterAPIMethods(apiHandler, conf) RegisterAPIMethods(apiHandler, configManager)
slog.Info("Starting Webserver...") slog.Info("Starting Webserver...")
server.StartWebserver(conf, apiHandler) server.StartWebserver(configManager, apiHandler)
slog.Info("Ready.") slog.Info("Ready.")
@ -76,39 +78,9 @@ func main() {
slog.Info("Done") slog.Info("Done")
} }
func LoadConfiguration(file string) (*definitions.Config, error) { func RegisterAPIMethods(apiHandler *jsonrpc.Handler, configManager *config.ConfigManager) {
var config definitions.Config apiHandler.Register("Config", &configAPI.Config{ConfigManager: configManager})
configFile, err := os.Open(file) apiHandler.Register("Firewall", &firewall.Firewall{ConfigManager: configManager})
if err != nil { apiHandler.Register("Network", &network.Network{ConfigManager: configManager})
return nil, fmt.Errorf("opening Config File %w", err) apiHandler.Register("Object", &object.Object{ConfigManager: configManager})
}
defer configFile.Close()
jsonParser := json.NewDecoder(configFile)
jsonParser.DisallowUnknownFields()
err = jsonParser.Decode(&config)
if err != nil {
return nil, fmt.Errorf("decoding Config File %w", err)
}
return &config, nil
}
func RegisterAPIMethods(apiHandler *jsonrpc.Handler, conf *definitions.Config) {
apiHandler.Register("Firewall", &firewall.Firewall{Conf: conf})
apiHandler.Register("Network", &network.Network{Conf: conf})
apiHandler.Register("Object", &object.Object{Conf: conf})
}
func apply(conf *definitions.Config) error {
fileContent, err := nftables.GenerateNfTablesFile(*conf)
if err != nil {
return fmt.Errorf("Generating nftables file %w", err)
}
err = nftables.ApplyNfTablesFile(fileContent)
if err != nil {
return fmt.Errorf("Applying nftables %w", err)
}
slog.Info("Wrote nftables File!")
return nil
} }