ipam is functioning with the basics =)

This commit is contained in:
Adora Laura Kalb 2023-03-15 16:43:20 +01:00
parent 386a2bd33f
commit 92118a60aa
9 changed files with 143 additions and 8 deletions

2
.gitignore vendored
View file

@ -21,7 +21,7 @@
go.work go.work
# build output # build output
output/ bin/
# vs code stuff # vs code stuff
.vscode/ .vscode/

14
Makefile Normal file
View file

@ -0,0 +1,14 @@
OUTPUT_FOLDER=bin
FILENAME=ipam
all: build
build:
go build -o ${OUTPUT_FOLDER}/${FILENAME} main.go
install:
cp ${OUTPUT_FOLDER}/${FILENAME} /usr/local/bin/${FILENAME}
clean:
go clean
rm -r ${OUTPUT_FOLDER}/

View file

@ -1,3 +1,28 @@
# ipam # ipam
This project is in development. There is no working version yet! This project is in development. There is no working version yet!
## CLI
```
ipam
A cli based ipam.
You can manage subnets, single ip addresses within those, and the corresponding A records.
PowerDNS and IPV6-Support will follow
Usage:
ipam [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
export Export current ipam configuration (not implemented)
help Help about any command
import Import ipam configuration (not implemented)
ip manage ip addresses
subnet Manage ip subnets
Flags:
-d, --debug Enable debug mode. (may print sensitive Information, so please watch out!)
-h, --help help for ipam
Use "ipam [command] --help" for more information about a command.
```

View file

@ -5,6 +5,7 @@ Copyright © 2023 Laura Kalb <dev@lauka.net>
package cmd package cmd
import ( import (
"errors"
"net/netip" "net/netip"
) )
@ -29,12 +30,42 @@ func (s Subnet) HasIP(ip netip.Addr) bool {
return iscontained return iscontained
} }
func (s Subnet) RemoveIP(ip netip.Addr) bool { // RemoveIP removes the Address object for given ip from
return true // the Address list of the subnet.
//
// Returns the changed Subnet and nil if delete was
// successful, or an empty Subnet and an error if
// ip could not be deleted.
func (s Subnet) RemoveIP(ip netip.Addr) (Subnet, error) {
var addrlist []Address
if !s.HasIP(ip) {
return Subnet{}, errors.New("IP " + ip.String() + " wasn't found in subnet " + s.Subnet.String())
}
for _, item := range s.Addresses {
if item.IP.Compare(ip) != 0 {
addrlist = append(addrlist, item)
}
}
s.Addresses = addrlist
return s, nil
} }
func (s Subnet) GetIP(ip netip.Addr) bool { // GetIP returns the Address object for the subnet with
return true // netip.Addr ip.
//
// Returns the Address object and true if a corresponding
// object was found, an empty Address and false otherwise.
func (s Subnet) GetIP(ip netip.Addr) (Address, bool) {
for _, item := range s.Addresses {
if item.IP.Compare(ip) == 0 {
return item, true
}
}
return Address{}, false
} }
type Address struct { type Address struct {

View file

@ -44,7 +44,7 @@ var ipaddCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
subnet, subnetexists := SearchBestSubnet(ip) subnet, subnetexists := FindBestSubnet(ip)
if !subnetexists { if !subnetexists {
fmt.Printf("[ERROR] Found no suitable subnet for IP %v\n", ipaddress) fmt.Printf("[ERROR] Found no suitable subnet for IP %v\n", ipaddress)

View file

@ -4,6 +4,10 @@ Copyright © 2023 Laura Kalb <dev@lauka.net>
package cmd package cmd
import ( import (
"fmt"
"net/netip"
"os"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -16,6 +20,38 @@ var ipdeleteCmd = &cobra.Command{
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Example: "ipam ip delete 192.168.0.1", Example: "ipam ip delete 192.168.0.1",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
ip, parseerr := netip.ParseAddr(args[0])
if parseerr != nil {
fmt.Println("[ERROR]", parseerr)
os.Exit(1)
}
subnet, subnetexists := FindBestSubnet(ip)
if !subnetexists {
fmt.Printf("[ERROR] Couldn't find IP %v\n", ip.String())
os.Exit(1)
}
address, _ := subnet.GetIP(ip)
subnet, removeerr := subnet.RemoveIP(ip)
if removeerr != nil {
fmt.Println("[ERROR]", removeerr)
os.Exit(1)
}
writeerr := WriteSubnet(subnet)
if writeerr != nil {
fmt.Println("[ERROR]", writeerr)
os.Exit(1)
}
if address.FQDN == "" {
fmt.Printf("deleted ip %v\n", address.IP.String())
} else {
fmt.Printf("deleted ip %v (%v)\n", address.IP.String(), address.FQDN)
}
}, },
} }

View file

@ -16,7 +16,7 @@ var ipeditCmd = &cobra.Command{
Aliases: []string{"e"}, Aliases: []string{"e"},
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Println("edit called") fmt.Println("not implemented yet; please delete and readd")
}, },
} }

View file

@ -5,6 +5,8 @@ package cmd
import ( import (
"fmt" "fmt"
"net/netip"
"os"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -16,8 +18,30 @@ var ipshowCmd = &cobra.Command{
Long: `Show IP and associated name`, Long: `Show IP and associated name`,
Aliases: []string{"s"}, Aliases: []string{"s"},
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Example: "ipam ip show 192.168.0.1",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Println("ip show called") ip, parseerr := netip.ParseAddr(args[0])
if parseerr != nil {
fmt.Println("[ERROR]", parseerr)
os.Exit(1)
}
subnet, subnetexists := FindBestSubnet(ip)
if !subnetexists {
fmt.Printf("[ERROR] Couldn't find IP %v\n", ip.String())
os.Exit(1)
}
addr, addrexists := subnet.GetIP(ip)
if !addrexists {
fmt.Printf("[ERROR] Couldn't find IP %v\n", ip.String())
os.Exit(1)
}
fmt.Printf("IP: %v\n", ip.String())
fmt.Printf("FQDN: %v\n", addr.FQDN)
fmt.Printf("Subnet: %v (%v)\n", subnet.Subnet.String(), subnet.Name)
}, },
} }

5
cmd/powerdns.go Normal file
View file

@ -0,0 +1,5 @@
/*
Copyright © 2023 Laura Kalb <dev@lauka.net>
*/
package cmd