diff --git a/client/src/App.vue b/client/src/App.vue
index 0a2887e..cacbc08 100644
--- a/client/src/App.vue
+++ b/client/src/App.vue
@@ -11,6 +11,7 @@ import ISNAT from '~icons/mdi/arrow-expand-right';
import IDNAT from '~icons/mdi/arrow-collapse-right';
import IConfig from '~icons/grommet-icons/document-config';
import IStaticRoutes from '~icons/material-symbols/drive-folder-upload-outline-sharp';
+import ITimeServer from '~icons/carbon/server-time';
enum NavState { Open, Reduced, Collapsed };
const NavStateCount = 3;
@@ -25,6 +26,7 @@ const navRoutes = {
"/object/addresses": { icon: IAddress, caption: "Addresses" },
"/object/services": { icon: IService, caption: "Services" },
"/service/dhcpv4servers": { icon: IService, caption: "DHCP v4" },
+ "/service/ntpservers": { icon: ITimeServer, caption: "NTP Server" },
"/config/config": { icon: IConfig, caption: "Config" },
};
diff --git a/client/src/definitions.ts b/client/src/definitions.ts
index 25ba949..a02d27e 100644
--- a/client/src/definitions.ts
+++ b/client/src/definitions.ts
@@ -177,5 +177,20 @@ export const editTypes: { [key: string]: { [key: string]: any } } = {
},
],
},
+ "ntpservers": {
+ name: "NTPServer",
+ validationSchema: toFormValidator(
+ zod.object({
+ }),
+ ),
+ sections: [
+ {
+ fields: [
+ { key: "interface", label: "Interface", as: "SingleSelect", props: { searchProvider: GetInterfaces } },
+ { key: "comment", label: "Comment", as: "MultilineTextBox" },
+ ],
+ },
+ ],
+ },
},
};
\ No newline at end of file
diff --git a/client/src/pages/service/NTPServers.vue b/client/src/pages/service/NTPServers.vue
new file mode 100644
index 0000000..5b3686f
--- /dev/null
+++ b/client/src/pages/service/NTPServers.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+ Create
+ Edit
+
+
+
+
\ No newline at end of file
diff --git a/internal/api/service/ntp_server.go b/internal/api/service/ntp_server.go
new file mode 100644
index 0000000..fca7519
--- /dev/null
+++ b/internal/api/service/ntp_server.go
@@ -0,0 +1,81 @@
+package service
+
+import (
+ "context"
+ "fmt"
+
+ "nfsense.net/nfsense/internal/definitions/service"
+)
+
+type GetNTPServerParameters struct {
+ ID uint
+}
+
+type GetNTPServerResult struct {
+ service.NTPServer
+}
+
+func (f *Service) GetNTPServer(ctx context.Context, params GetNTPServerParameters) (GetNTPServerResult, error) {
+ if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Service.NTPServers) {
+ return GetNTPServerResult{}, fmt.Errorf("NTPServer does not Exist")
+ }
+
+ return GetNTPServerResult{
+ NTPServer: f.ConfigManager.GetPendingConfig().Service.NTPServers[params.ID],
+ }, nil
+}
+
+type GetNTPServersResult struct {
+ NTPServers []service.NTPServer `json:"ntp_servers"`
+}
+
+func (f *Service) GetNTPServers(ctx context.Context, params struct{}) (GetNTPServersResult, error) {
+ return GetNTPServersResult{
+ NTPServers: f.ConfigManager.GetPendingConfig().Service.NTPServers,
+ }, nil
+}
+
+type CreateNTPServerParameters struct {
+ service.NTPServer
+}
+
+func (f *Service) CreateNTPServer(ctx context.Context, params CreateNTPServerParameters) (struct{}, error) {
+ t, conf := f.ConfigManager.StartTransaction()
+ defer t.Discard()
+
+ conf.Service.NTPServers = append(conf.Service.NTPServers, params.NTPServer)
+ return struct{}{}, t.Commit()
+}
+
+type UpdateNTPServerParameters struct {
+ Index uint64 `json:"index"`
+ NTPServer service.NTPServer `json:"ntp_server"`
+}
+
+func (f *Service) UpdateNTPServer(ctx context.Context, params UpdateNTPServerParameters) (struct{}, error) {
+ if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.NTPServers) {
+ return struct{}{}, fmt.Errorf("NTPServer does not Exist")
+ }
+
+ t, conf := f.ConfigManager.StartTransaction()
+ defer t.Discard()
+
+ conf.Service.NTPServers[params.Index] = params.NTPServer
+ return struct{}{}, t.Commit()
+}
+
+type DeleteNTPServerParameters struct {
+ Index uint64 `json:"index"`
+}
+
+func (f *Service) DeleteNTPServer(ctx context.Context, params DeleteNTPServerParameters) (struct{}, error) {
+ if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.NTPServers) {
+ return struct{}{}, fmt.Errorf("NTPServer does not Exist")
+ }
+
+ t, conf := f.ConfigManager.StartTransaction()
+ defer t.Discard()
+
+ conf.Service.NTPServers = append(conf.Service.NTPServers[:params.Index], conf.Service.NTPServers[params.Index+1:]...)
+ return struct{}{}, t.Commit()
+}