diff --git a/cmd/classes.go b/cmd/classes.go index 0082355..7abd575 100644 --- a/cmd/classes.go +++ b/cmd/classes.go @@ -7,13 +7,16 @@ package cmd import ( "errors" "net/netip" + "time" ) type Subnet struct { - Subnet netip.Prefix - Name string - Vlan string - Addresses []Address + Subnet netip.Prefix `json:"subnet"` + Name string `json:"name"` + Vlan string `json:"vlan"` + ChangedAt time.Time `json:"changedat,omitempty"` + ChangedBy string `json:"changedby,omitempty"` + Addresses []Address `json:"addresses"` } // HasIP checks if a Subnet already contains given netip.Addr. @@ -69,6 +72,8 @@ func (s Subnet) GetIP(ip netip.Addr) (Address, bool) { } type Address struct { - IP netip.Addr - FQDN string + IP netip.Addr `json:"ip"` + FQDN string `json:"fqdn"` + ChangedAt time.Time `json:"changedat,omitempty"` + ChangedBy string `json:"changedby,omitempty"` } diff --git a/cmd/ip-add.go b/cmd/ip-add.go index 4fed034..55feb6f 100644 --- a/cmd/ip-add.go +++ b/cmd/ip-add.go @@ -8,6 +8,8 @@ import ( "fmt" "net/netip" "os" + "os/user" + "time" "github.com/spf13/cobra" ) @@ -57,9 +59,10 @@ var ipaddCmd = &cobra.Command{ os.Exit(1) } - subnet.Addresses = append(subnet.Addresses, Address{ip, hostname}) + currentuser, _ := user.Current() + subnet.Addresses = append(subnet.Addresses, Address{ip, hostname, time.Now(), currentuser.Username}) - writeerr := WriteSubnet(subnet) + writeerr := subnet.WriteSubnet() if writeerr != nil { fmt.Println("[ERROR]", writeerr) os.Exit(1) diff --git a/cmd/storage.go b/cmd/storage.go index d316680..334d662 100644 --- a/cmd/storage.go +++ b/cmd/storage.go @@ -5,7 +5,7 @@ Copyright © 2023 Laura Kalb package cmd import ( - "bufio" + "encoding/json" "fmt" "net/netip" "os" @@ -81,7 +81,9 @@ func ListSubnets() []string { os.Exit(1) } for _, element := range subnetfiles { - subnets = append(subnets, strings.Replace(element.Name(), "_", "/", 1)) + a := strings.Replace(element.Name(), "_", "/", 1) + a = strings.Replace(a, ".json", "", 1) + subnets = append(subnets, a) } return subnets @@ -91,7 +93,7 @@ func ListSubnets() []string { // file. // // Returns nil on success or the error that happened. -func WriteSubnet(subnet Subnet) error { +func (s Subnet) WriteSubnet() error { var datadir string = viper.GetString("DataPath") _, direrr := os.Stat(datadir) @@ -103,7 +105,9 @@ func WriteSubnet(subnet Subnet) error { } } - filename := datadir + strings.Replace(subnet.Subnet.String(), "/", "_", 1) + filename := datadir + strings.Replace(s.Subnet.String(), "/", "_", 1) + ".json" + + data, _ := json.Marshal(s) file, fileerr := os.Create(filename) if fileerr != nil { @@ -112,35 +116,12 @@ func WriteSubnet(subnet Subnet) error { } defer file.Close() - _, suberr := file.WriteString(subnet.Subnet.String() + "\n") - if suberr != nil { - fmt.Println("[ERROR]", suberr) + _, writeerr := file.Write(data) + if writeerr != nil { + fmt.Println("[ERROR]", writeerr) os.Exit(1) } - _, nameerr := file.WriteString(subnet.Name + "\n") - if nameerr != nil { - fmt.Println("[ERROR]", nameerr) - os.Exit(1) - } - - _, vlanerr := file.WriteString(subnet.Vlan + "\n") - if vlanerr != nil { - fmt.Println("[ERROR]", vlanerr) - os.Exit(1) - } - - if len(subnet.Addresses) != 0 { - subnetsorted := SortAddresses(subnet.Addresses) - for _, element := range subnetsorted { - _, err := file.WriteString(element.IP.String() + ":" + element.FQDN + "\n") - if err != nil { - fmt.Println("[ERROR]", err) - os.Exit(1) - } - } - } - return nil } @@ -151,43 +132,17 @@ func WriteSubnet(subnet Subnet) error { // successful, an empty Subnet object and the error otherwise. func GetSubnet(net netip.Prefix) (Subnet, error) { var datadir string = viper.GetString("DataPath") - filename := datadir + strings.Replace(net.String(), "/", "_", 1) + filename := datadir + strings.Replace(net.String(), "/", "_", 1) + ".json" var subnet Subnet = Subnet{} - // open file - file, openerr := os.Open(filename) - if openerr != nil { - return Subnet{}, openerr - } - // remember to close the file at the end of the program - defer file.Close() - - // read the file line by line using scanner - scanner := bufio.NewScanner(file) - - var counter int = 0 - for scanner.Scan() { - switch counter { - case 0: - subnet.Subnet, _ = netip.ParsePrefix(scanner.Text()) - - case 1: - subnet.Name = scanner.Text() - - case 2: - subnet.Vlan = scanner.Text() - - default: - s := strings.Split(scanner.Text(), ":") - ip, _ := netip.ParseAddr(s[0]) - a := Address{ip, s[1]} - subnet.Addresses = append(subnet.Addresses, a) - } - counter = counter + 1 + content, readerr := os.ReadFile(filename) + if readerr != nil { + return Subnet{}, readerr } - if scanerr := scanner.Err(); scanerr != nil { - return Subnet{}, openerr + marsherr := json.Unmarshal(content, &subnet) + if marsherr != nil { + return Subnet{}, marsherr } return subnet, nil @@ -213,7 +168,7 @@ func SortAddresses(list []Address) []Address { // Returns nil on success, or a *PathError on failure func DeleteSubnet(net netip.Prefix) error { var datadir string = viper.GetString("DataPath") - filename := datadir + strings.Replace(net.String(), "/", "_", 1) + filename := datadir + strings.Replace(net.String(), "/", "_", 1) + ".json" removeerr := os.Remove(filename) if removeerr != nil { diff --git a/cmd/subnet-add.go b/cmd/subnet-add.go index 7a30dd7..8f867eb 100644 --- a/cmd/subnet-add.go +++ b/cmd/subnet-add.go @@ -8,6 +8,8 @@ import ( "fmt" "net/netip" "os" + "os/user" + "time" "github.com/spf13/cobra" ) @@ -59,12 +61,16 @@ var subnetaddCmd = &cobra.Command{ os.Exit(1) } + currentuser, _ := user.Current() + subnetobject := Subnet{} subnetobject.Subnet = ipnet subnetobject.Name = netname subnetobject.Vlan = vlanid + subnetobject.ChangedAt = time.Now() + subnetobject.ChangedBy = currentuser.Username - writeerr := WriteSubnet(subnetobject) + writeerr := subnetobject.WriteSubnet() if writeerr != nil { fmt.Println("[ERROR]", writeerr)