package database import ( // Standard "encoding/json" "errors" "os" "sync" ) // Database type database struct { path string mutex sync.Mutex data databaseData } // Database Data type databaseData struct { IPv4Address string `json:"ipv4_address"` IPv6Address string `json:"ipv6_address"` DDNSEntries []DatabaseDataDDNSEntry `json:"ddns_entries"` } // Database Data DDNS Entry type DatabaseDataDDNSEntry struct { Record string `json:"record"` Updated bool `json:"updated"` Provider string `json:"provider"` ProviderData interface{} `json:"provider_data"` } // Database Data DDNS Entry Provider Data Cloudflare type DatabaseDataDDNSEntryProviderDataCloudflare struct { APIToken string `json:"api_token"` ZoneID string `json:"zone_id"` } // Save func (db *database) save() error { // Marshal Data jsonData, err := json.MarshalIndent(db.data, "", " ") // Handle Error if err != nil { return err } // Save Data return os.WriteFile(db.path, jsonData, 0644) } // Load func (db *database) load() error { // Load Data jsonData, err := os.ReadFile(db.path) // Handle Error if err != nil { return err } // Unmarshal Data err = json.Unmarshal(jsonData, &db.data) // Handle Error if err != nil { return err } // Unmarshal DDNS Entries for entryNumber, entry := range db.data.DDNSEntries { switch entry.Provider { // Cloudflare case "Cloudflare": // Entry Data var entryData DatabaseDataDDNSEntryProviderDataCloudflare // Marshal Entry Data data, err := json.Marshal(entry.ProviderData) // Handle Error if err != nil { return err } // Unmarshal Entry Data err = json.Unmarshal(data, &entryData) // Handle Error if err != nil { return err } // Set Provider Data db.data.DDNSEntries[entryNumber].ProviderData = entryData // Default default: return errors.New("unknown ddns entry provider") } } // Success return nil } // Create func Create(path string) *database { // Database db := database{ path: path, mutex: sync.Mutex{}, data: databaseData{}, } // Check File _, err := os.Stat(db.path) // File Does Not Exist if os.IsNotExist(err) { // Create File file, err := os.Create(db.path) // Handle Error if err != nil { panic(err) } // Close File file.Close() // Save Database err = db.save() // Handle Error if err != nil { panic(err) } // Success return &db } else if err != nil { // Handle Error panic(err) } // Load err = db.load() // Handle Error if err != nil { panic(err) } // Success return &db } // Set IPv4 Address func (db *database) SetIPv4Address(ipv4Address string) error { // Lock db.mutex.Lock() defer db.mutex.Unlock() // Set IPv4 Address db.data.IPv4Address = ipv4Address // Reset Updated for entryNumber := range db.data.DDNSEntries { db.data.DDNSEntries[entryNumber].Updated = false } // Save return db.save() } // Set IPv6 Address func (db *database) SetIPv6Address(ipv6Address string) error { // Lock db.mutex.Lock() defer db.mutex.Unlock() // Set IPv6 Address db.data.IPv6Address = ipv6Address // Reset Updated for entryNumber := range db.data.DDNSEntries { db.data.DDNSEntries[entryNumber].Updated = false } // Save return db.save() } // Get IPv4 Address func (db *database) GetIPv4Address() string { return db.data.IPv4Address } // Get IPv6 Address func (db *database) GetIPv6Address() string { return db.data.IPv6Address } // Add Entry func (db *database) AddEntry(entry DatabaseDataDDNSEntry) error { // Lock db.mutex.Lock() defer db.mutex.Unlock() // Check Entry for _, existingEntry := range db.data.DDNSEntries { if entry.Record == existingEntry.Record { return errors.New("entry exists") } } // Add Entry db.data.DDNSEntries = append(db.data.DDNSEntries, entry) // Save return db.save() } // Update Entry func (db *database) UpdateEntry(record string) error { // Lock db.mutex.Lock() defer db.mutex.Unlock() // Update Entry for entryNumber, entry := range db.data.DDNSEntries { if entry.Record == record { db.data.DDNSEntries[entryNumber].Updated = true break } } // Save return db.save() } // Get Entries func (db *database) GetEntries() []DatabaseDataDDNSEntry { return db.data.DDNSEntries } // Delete Entry func (db *database) DeleteEntry(record string) error { // Lock db.mutex.Lock() defer db.mutex.Unlock() // Delete Entry for entryNumber, entry := range db.data.DDNSEntries { if entry.Record == record { db.data.DDNSEntries = append(db.data.DDNSEntries[:entryNumber], db.data.DDNSEntries[entryNumber+1:]...) } } // Save return db.save() }