mirror of
https://codeberg.org/lauralani/ipam.git
synced 2024-11-24 04:30:02 +01:00
ipam is functioning with the basics =)
This commit is contained in:
parent
386a2bd33f
commit
92118a60aa
9 changed files with 143 additions and 8 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -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
14
Makefile
Normal 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}/
|
25
README.md
25
README.md
|
@ -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.
|
||||||
|
```
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
5
cmd/powerdns.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2023 Laura Kalb <dev@lauka.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
Loading…
Reference in a new issue