From 70d69f04cf98831957fb725c665564b39886d4a5 Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Sat, 1 Apr 2023 18:17:48 +0200 Subject: [PATCH] Use Config Manager --- .../api/firewall/destination_nat_rules.go | 2 +- internal/api/firewall/firewall.go | 4 +- internal/api/firewall/forward_rules.go | 2 +- internal/api/firewall/source_nat_rules.go | 2 +- internal/api/network/interfaces.go | 33 ++------- internal/api/network/network.go | 6 +- internal/api/object/addresses.go | 14 ++-- internal/api/object/object.go | 4 +- internal/api/object/services.go | 14 ++-- internal/server/server.go | 4 +- main.go | 74 ++++++------------- 11 files changed, 55 insertions(+), 104 deletions(-) diff --git a/internal/api/firewall/destination_nat_rules.go b/internal/api/firewall/destination_nat_rules.go index 8081ce7..95a25f1 100644 --- a/internal/api/firewall/destination_nat_rules.go +++ b/internal/api/firewall/destination_nat_rules.go @@ -12,6 +12,6 @@ type GetDestinationNATRulesResult struct { func (f *Firewall) GetDestinationNATRules(ctx context.Context, params struct{}) (GetDestinationNATRulesResult, error) { return GetDestinationNATRulesResult{ - DestinationNATRules: f.Conf.Firewall.DestinationNATRules, + DestinationNATRules: f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules, }, nil } diff --git a/internal/api/firewall/firewall.go b/internal/api/firewall/firewall.go index 31ef0ec..1bde05c 100644 --- a/internal/api/firewall/firewall.go +++ b/internal/api/firewall/firewall.go @@ -1,9 +1,9 @@ package firewall import ( - "nfsense.net/nfsense/internal/definitions" + "nfsense.net/nfsense/internal/config" ) type Firewall struct { - Conf *definitions.Config + ConfigManager *config.ConfigManager } diff --git a/internal/api/firewall/forward_rules.go b/internal/api/firewall/forward_rules.go index abe7caf..4323f3b 100644 --- a/internal/api/firewall/forward_rules.go +++ b/internal/api/firewall/forward_rules.go @@ -12,6 +12,6 @@ type GetForwardRulesResult struct { func (f *Firewall) GetForwardRules(ctx context.Context, params struct{}) (GetForwardRulesResult, error) { return GetForwardRulesResult{ - ForwardRules: f.Conf.Firewall.ForwardRules, + ForwardRules: f.ConfigManager.GetPendingConfig().Firewall.ForwardRules, }, nil } diff --git a/internal/api/firewall/source_nat_rules.go b/internal/api/firewall/source_nat_rules.go index 06f5d6a..6f36ed4 100644 --- a/internal/api/firewall/source_nat_rules.go +++ b/internal/api/firewall/source_nat_rules.go @@ -12,6 +12,6 @@ type GetSourceNATRulesResult struct { func (f *Firewall) GetSourceNATRules(ctx context.Context, params struct{}) (GetSourceNATRulesResult, error) { return GetSourceNATRulesResult{ - SourceNATRules: f.Conf.Firewall.SourceNATRules, + SourceNATRules: f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules, }, nil } diff --git a/internal/api/network/interfaces.go b/internal/api/network/interfaces.go index d7721c7..9afdda0 100644 --- a/internal/api/network/interfaces.go +++ b/internal/api/network/interfaces.go @@ -5,7 +5,6 @@ import ( "fmt" "nfsense.net/nfsense/internal/definitions" - "nfsense.net/nfsense/internal/interfaces" ) type GetInterfacesResult struct { @@ -14,7 +13,7 @@ type GetInterfacesResult struct { func (f *Network) GetInterfaces(ctx context.Context, params struct{}) (GetInterfacesResult, error) { return GetInterfacesResult{ - Interfaces: f.Conf.Network.Interfaces, + Interfaces: f.ConfigManager.GetPendingConfig().Network.Interfaces, }, nil } @@ -24,12 +23,12 @@ type CreateInterfaceParameters struct { } 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 { 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 } @@ -39,12 +38,12 @@ type UpdateInterfaceParameters struct { } 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 { 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 } @@ -53,29 +52,11 @@ type DeleteInterfaceParameters struct { } 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 { 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 } - -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 -} diff --git a/internal/api/network/network.go b/internal/api/network/network.go index 178778b..e27aaed 100644 --- a/internal/api/network/network.go +++ b/internal/api/network/network.go @@ -1,9 +1,7 @@ package network -import ( - "nfsense.net/nfsense/internal/definitions" -) +import "nfsense.net/nfsense/internal/config" type Network struct { - Conf *definitions.Config + ConfigManager *config.ConfigManager } diff --git a/internal/api/object/addresses.go b/internal/api/object/addresses.go index 0cdad24..9c2cbee 100644 --- a/internal/api/object/addresses.go +++ b/internal/api/object/addresses.go @@ -13,7 +13,7 @@ type GetAddressesResult struct { func (f *Object) GetAddresses(ctx context.Context, params struct{}) (GetAddressesResult, error) { return GetAddressesResult{ - Addresses: f.Conf.Object.Addresses, + Addresses: f.ConfigManager.GetPendingConfig().Object.Addresses, }, nil } @@ -23,12 +23,12 @@ type CreateAddressParameters struct { } 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 { 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 } @@ -38,12 +38,12 @@ type UpdateAddressParameters struct { } 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 { 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 } @@ -52,11 +52,11 @@ type DeleteAddressParameters struct { } 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 { 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 } diff --git a/internal/api/object/object.go b/internal/api/object/object.go index 3324fca..e34d905 100644 --- a/internal/api/object/object.go +++ b/internal/api/object/object.go @@ -1,7 +1,7 @@ package object -import "nfsense.net/nfsense/internal/definitions" +import "nfsense.net/nfsense/internal/config" type Object struct { - Conf *definitions.Config + ConfigManager *config.ConfigManager } diff --git a/internal/api/object/services.go b/internal/api/object/services.go index f909d72..85c4a8a 100644 --- a/internal/api/object/services.go +++ b/internal/api/object/services.go @@ -13,7 +13,7 @@ type GetServicesResult struct { func (f *Object) GetServices(ctx context.Context, params struct{}) (GetServicesResult, error) { return GetServicesResult{ - Services: f.Conf.Object.Services, + Services: f.ConfigManager.GetPendingConfig().Object.Services, }, nil } @@ -23,12 +23,12 @@ type CreateServiceParameters struct { } 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 { 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 } @@ -38,12 +38,12 @@ type UpdateServiceParameters struct { } 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 { 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 } @@ -52,11 +52,11 @@ type DeleteServiceParameters struct { } 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 { 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 } diff --git a/internal/server/server.go b/internal/server/server.go index d54c9ba..cfa0fe7 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -8,7 +8,7 @@ import ( "golang.org/x/exp/slog" - "nfsense.net/nfsense/internal/definitions" + "nfsense.net/nfsense/internal/config" "nfsense.net/nfsense/internal/jsonrpc" "nfsense.net/nfsense/internal/session" ) @@ -18,7 +18,7 @@ var mux = http.NewServeMux() var apiHandler *jsonrpc.Handler var stopCleanup chan struct{} -func StartWebserver(conf *definitions.Config, _apiHandler *jsonrpc.Handler) { +func StartWebserver(configManager *config.ConfigManager, _apiHandler *jsonrpc.Handler) { server.Addr = ":8080" server.Handler = mux apiHandler = _apiHandler diff --git a/main.go b/main.go index 9681332..f5b375c 100644 --- a/main.go +++ b/main.go @@ -2,21 +2,19 @@ package main import ( "context" - "encoding/json" "flag" - "fmt" "os" "os/signal" "syscall" "time" "golang.org/x/exp/slog" + configAPI "nfsense.net/nfsense/internal/api/config" "nfsense.net/nfsense/internal/api/firewall" "nfsense.net/nfsense/internal/api/network" "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/nftables" "nfsense.net/nfsense/internal/server" ) @@ -26,27 +24,31 @@ func main() { slog.Info("Starting...") - conf, err := LoadConfiguration("config.json") + configManager := config.CreateConfigManager() + + err := configManager.LoadCurrentConfigFromDisk() if err != nil { - slog.Error("Loading Config", err) + slog.Error("Loading Current Config", err) os.Exit(1) } - slog.Info("Config Loaded", "config", conf) + slog.Info("Config Loaded") - err = definitions.ValidateConfig(conf) + err = configManager.LoadPendingConfigFromDisk() if err != nil { - slog.Error("Validating Config", err) - os.Exit(1) + slog.Error("Loading Pending Config", err) + err = configManager.DiscardPendingConfig() + if err != nil { + slog.Error("Discarding Pending Config", err) + os.Exit(1) + } } - slog.Info("Validating Config...") - if *applyPtr { slog.Info("Applying Config...") - err := apply(conf) + err := configManager.ApplyPendingChanges() if err != nil { - slog.Error("Applying Config", err) + slog.Error("Applying Pending Config", err) os.Exit(1) } slog.Info("Config Applied, Exiting...") @@ -55,10 +57,10 @@ func main() { slog.Info("Setup API...") apiHandler := jsonrpc.NewHandler(100 << 20) - RegisterAPIMethods(apiHandler, conf) + RegisterAPIMethods(apiHandler, configManager) slog.Info("Starting Webserver...") - server.StartWebserver(conf, apiHandler) + server.StartWebserver(configManager, apiHandler) slog.Info("Ready.") @@ -76,39 +78,9 @@ func main() { slog.Info("Done") } -func LoadConfiguration(file string) (*definitions.Config, error) { - var config definitions.Config - configFile, err := os.Open(file) - if err != nil { - return nil, fmt.Errorf("opening Config File %w", err) - } - 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 +func RegisterAPIMethods(apiHandler *jsonrpc.Handler, configManager *config.ConfigManager) { + apiHandler.Register("Config", &configAPI.Config{ConfigManager: configManager}) + apiHandler.Register("Firewall", &firewall.Firewall{ConfigManager: configManager}) + apiHandler.Register("Network", &network.Network{ConfigManager: configManager}) + apiHandler.Register("Object", &object.Object{ConfigManager: configManager}) }