add a whole lot of functionality :3

This commit is contained in:
Adora Laura Kalb 2023-03-14 17:21:49 +01:00
parent 5af155dfc7
commit 6154f16e11
7 changed files with 129 additions and 36 deletions

43
cmd/classes.go Normal file
View file

@ -0,0 +1,43 @@
/*
Copyright © 2023 Laura Kalb <dev@lauka.net>
*/
package cmd
import (
"net/netip"
)
type Subnet struct {
Subnet netip.Prefix
Name string
Vlan string
Addresses []Address
}
// HasIP checks if a Subnet already contains given netip.Addr.
// Returns true if the IP already is present, false otherwise.
func (s Subnet) HasIP(ip netip.Addr) bool {
iscontained := false
for _, element := range s.Addresses {
if element.IP.Compare(ip) == 0 {
iscontained = true
}
}
return iscontained
}
func (s Subnet) RemoveIP(ip netip.Addr) bool {
return true
}
func (s Subnet) GetIP(ip netip.Addr) bool {
return true
}
type Address struct {
IP netip.Addr
FQDN string
}

View file

@ -52,6 +52,11 @@ var ipaddCmd = &cobra.Command{
os.Exit(1)
}
if subnet.HasIP(ip) {
fmt.Printf("[ERROR] IP %v already exists in subnet %v\n", ip.String(), subnet.Subnet.String())
os.Exit(1)
}
subnet.Addresses = append(subnet.Addresses, Address{ip, hostname})
writeerr := WriteSubnet(subnet)

View file

@ -4,8 +4,6 @@ Copyright © 2023 Laura Kalb <dev@lauka.net>
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
@ -16,8 +14,8 @@ var ipdeleteCmd = &cobra.Command{
Long: `Delete an IP address`,
Aliases: []string{"d"},
Args: cobra.ExactArgs(1),
Example: "ipam ip delete 192.168.0.1",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("ip delete called")
},
}

View file

@ -15,18 +15,6 @@ import (
"github.com/spf13/viper"
)
type Subnet struct {
Subnet netip.Prefix
Name string
Vlan string
Addresses []Address
}
type Address struct {
IP netip.Addr
FQDN string
}
// SearchBestSubnet tries to load the most fitting IP subnet file
// on disk. It takes an IP object and tries to get the best subnet
// (meaning the subnet with the smallest subnet size).
@ -218,3 +206,19 @@ func SortAddresses(list []Address) []Address {
})
return list
}
// DeleteSubnet deletes the subnet file on disk for netip.Prefix
// net.
//
// 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)
removeerr := os.Remove(filename)
if removeerr != nil {
return removeerr
} else {
return nil
}
}

View file

@ -38,7 +38,7 @@ var subnetaddCmd = &cobra.Command{
// Parse subnet into ParseCIDR to test if it's a valid subnet
// _, ipnet, err := net.ParseCIDR(subnet)
ipnet, err := netip.ParsePrefix(subnet)
ipnet, parseerr := netip.ParsePrefix(subnet)
// Exit if subnet already exists, no need to add it then
if SubnetExists(ipnet) {
@ -47,8 +47,8 @@ var subnetaddCmd = &cobra.Command{
}
// Exit if parsed value is no valid IP
if err != nil {
fmt.Println("[ERROR]", err)
if parseerr != nil {
fmt.Println("[ERROR]", parseerr)
os.Exit(1)
}
@ -67,15 +67,11 @@ var subnetaddCmd = &cobra.Command{
writeerr := WriteSubnet(subnetobject)
if writeerr != nil {
fmt.Println("[ERROR]", err)
fmt.Println("[ERROR]", writeerr)
os.Exit(1)
}
if vlanid == "-" {
fmt.Printf("added subnet:\nnet: %v\nname: %v\n", subnet, netname)
} else {
fmt.Printf("added subnet:\nnet: %v\nname: %v\nvlan: %v\n", subnet, netname, vlanid)
}
},
}

View file

@ -5,6 +5,7 @@ package cmd
import (
"fmt"
"net/netip"
"os"
"github.com/spf13/cobra"
@ -17,20 +18,27 @@ var subnetdeleteCmd = &cobra.Command{
Long: `Delete a subnet from the ipam.`,
Args: cobra.ExactArgs(1),
Aliases: []string{"d"},
Example: "ipam subnet delete 192.168.0.0/24",
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 1 {
fmt.Println("Error: Too few arguments!")
fmt.Print("Usage:\n ipam subnet delete [subnet]")
subnet, parseerr := netip.ParsePrefix(args[0])
if parseerr != nil {
fmt.Println("[ERROR]", parseerr)
os.Exit(1)
}
if len(args) > 1 {
fmt.Println("Error: Too many arguments!")
fmt.Print("Usage:\n ipam subnet delete [subnet]")
os.Exit(1)
}
subnet := args[0]
fmt.Printf("Deleting %v\n", subnet)
var confirmation string
fmt.Printf("[WARNING] Do you really want to delete subnet %v? [y/N] ", subnet.String())
fmt.Scan(&confirmation)
if (confirmation == "y") || (confirmation == "Y") {
deleteerr := DeleteSubnet(subnet)
if deleteerr != nil {
fmt.Println("[ERROR]", deleteerr)
os.Exit(1)
} else {
fmt.Printf("deleted subnet %v\n", subnet.String())
}
}
},
}

View file

@ -5,6 +5,10 @@ package cmd
import (
"fmt"
"math"
"net/netip"
"os"
"sort"
"github.com/spf13/cobra"
)
@ -16,8 +20,43 @@ var subnetlistCmd = &cobra.Command{
Long: `List all subnets`,
Aliases: []string{"l"},
Args: cobra.ExactArgs(0),
Example: "cmdb subnet list",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("subnet list called")
verbose, _ := cmd.Flags().GetBool("verbose")
subnetlist := ListSubnets()
var subnets []Subnet
for _, subnet := range subnetlist {
prefix, _ := netip.ParsePrefix(subnet)
net, err := GetSubnet(prefix)
if err != nil {
fmt.Println("[ERROR]", err)
os.Exit(1)
}
subnets = append(subnets, net)
}
sort.Slice(subnets, func(i, j int) bool {
return subnets[i].Subnet.Addr().Less(subnets[j].Subnet.Addr())
})
for _, subnet := range subnets {
if verbose {
var numip, freeip int
if subnet.Subnet.Addr().Is4() {
hostbits := float64(32 - subnet.Subnet.Bits())
numip = int(math.Pow(2, hostbits)) - 2
freeip = numip - len(subnet.Addresses)
fmt.Printf("%v:\t%v\t(vl: %v)\tfree: %v\n", subnet.Subnet, subnet.Name, subnet.Vlan, freeip)
} else {
fmt.Printf("%v:\t%v\t(vl: %v)\n", subnet.Subnet, subnet.Name, subnet.Vlan)
}
} else {
fmt.Printf("%v:\t%v\t(vl: %v)\n", subnet.Subnet, subnet.Name, subnet.Vlan)
}
}
},
}
@ -32,5 +71,5 @@ func init() {
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// listCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
subnetlistCmd.Flags().BoolP("verbose", "v", false, "Show verbose output like free IPs")
}