- Notifications
You must be signed in to change notification settings - Fork43
golang grpc service and library for ip address management
License
metal-stack/go-ipam
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
go-ipam is a module to handle IP address management. It can operate on networks, prefixes and IPs.
It also comes as a ready to go microservice which offers a grpc api.
Most obvious this library is all about IP management. The main purpose is to acquire and release an IP, or a bunch ofIP's from prefixes.
A prefix is a network with IP and mask, typically in the form of192.168.0.0/24. To be able to manage IPs you have to create a prefix first.
Library Example usage:
package mainimport ("context""fmt""time" goipam"github.com/metal-stack/go-ipam")funcmain() {// The background contextbgCtx:=context.Background()// Create a ipamer with in memory storageipam:=goipam.New(bgCtx)// Optionally, we can pass around a context for a given namespacenamespace:="tenant-a"err:=ipam.CreateNamespace(bgCtx,namespace)iferr!=nil {panic(err) }ctx:=goipam.NewContextWithNamespace(bgCtx,namespace)ctx,cancel:=context.WithTimeout(ctx,5*time.Second)defercancel()// Create a prefix to manage some IPsprefix,err:=ipam.NewPrefix(ctx,"192.168.0.0/24")iferr!=nil {panic(err) }// Acquire and release an IP with this prefixip,err:=ipam.AcquireIP(ctx,prefix.Cidr)iferr!=nil {panic(err) }fmt.Printf("got IP: %s\n",ip.IP)prefix,err=ipam.ReleaseIP(ctx,ip)iferr!=nil {panic(err) }fmt.Printf("IP: %s released.\n",ip.IP)// Now a IPv6 Super Prefix with Child Prefixesprefix,err=ipam.NewPrefix(ctx,"2001:aabb::/48")iferr!=nil {panic(err) }cp1,err:=ipam.AcquireChildPrefix(ctx,prefix.Cidr,64)iferr!=nil {panic(err) }fmt.Printf("got Prefix: %s\n",cp1)cp2,err:=ipam.AcquireChildPrefix(ctx,prefix.Cidr,72)iferr!=nil {panic(err) }fmt.Printf("got Prefix: %s\n",cp2)ip21,err:=ipam.AcquireIP(ctx,cp2.Cidr)iferr!=nil {panic(err) }fmt.Printf("got IP: %s\n",ip21.IP)}
First start the go-ipam container with the database backend of your choice already up and running. For example if you have a postgres database for storing the ipam data, you could run the grpc service like so:
docker run -it --rm ghcr.io/metal-stack/go-ipam postgres
From a client perspective you can now talk to this service via grpc.
GRPC Example usage:
package mainimport ("http""github.com/bufbuild/connect-go" v1"github.com/metal-stack/go-ipam/api/v1""github.com/metal-stack/go-ipam/api/v1/apiv1connect")funcmain() {c:=apiv1connect.NewIpamServiceClient(http.DefaultClient,"http://localhost:9090",connect.WithGRPC(), )bgCtx:=context.Background()// Optional with Namespacectx:=goipam.NewContextWithNamespace(bgCtx,"tenant-a")result,err:=c.CreatePrefix(ctx,connect.NewRequest(&v1.CreatePrefixRequest{Cidr:"192.168.0.0/16",}))iferr!=nil {panic(err) }fmt.Println("Prefix:%q created",result.Msg.GetPrefix().GetCidr())}
There is also acli provided in the container which can be used to make calls to the grpc endpoint manually:
docker run -it --rm --entrypoint /cli ghcr.io/metal-stack/go-ipam
http://localhost:2112/metrics
go tool pprof -http :8080 localhost:2113/debug/pprof/heapgo tool pprof -http :8080 localhost:2113/debug/pprof/goroutine
Ensure you have docker with compose support installed. Then execute the following command:
docker compose up -d# check if up and runningdocker compose psNAME IMAGE COMMAND SERVICE CREATED STATUS PORTSgo-ipam-ipam-1 go-ipam"/server postgres" ipam 14 seconds ago Up 13 seconds (healthy) 0.0.0.0:9090->9090/tcp, :::9090->9090/tcpgo-ipam-postgres-1 postgres:alpine"docker-entrypoint.s…" postgres 8 minutes ago Up 13 seconds 5432/tcp# Then execute the cli to create prefixes and acquire ipsdocker composeexec ipam /cli prefix create --cidr 192.168.0.0/16prefix:"192.168.0.0/16" createddocker composeexec ipam /cli ip acquire --prefix 192.168.0.0/16ip:"192.168.0.1" acquired# Queries can also made against the Rest api like so:curl -v -X POST -d'{}' -H'Content-Type: application/json' localhost:9090/api.v1.IpamService/ListPrefixes
| Database | Acquire Child Prefix | Acquire IP | New Prefix | Prefix Overlap | Production-Ready | Geo-Redundant |
|---|---|---|---|---|---|---|
| In-Memory | 106,861/sec | 196,687/sec | 330,578/sec | 248/sec | N | N |
| File | N | N | ||||
| KeyDB | 777/sec | 975/sec | 2,271/sec | Y | Y | |
| Redis | 773/sec | 958/sec | 2,349/sec | Y | N | |
| MongoDB | 415/sec | 682/sec | 772/sec | Y | Y | |
| Etcd | 258/sec | 368/sec | 533/sec | Y | N | |
| Postgres | 203/sec | 331/sec | 472/sec | Y | N | |
| CockroachDB | 170/sec | 300/sec | 470/sec | Y | Y |
The benchmarks above were performed using:
- cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
- postgres:17-alpine
- cockroach:v24.1.0
- redis:7.4-alpine
- keydb:alpine_x86_64_v6.3.1
- etcd:v3.5.15
- mongodb:7
| Database | Details |
|---|---|
| KeyDB | |
| Redis | |
| MongoDB | mongodb-go compatibility |
| Etcd | |
| Postgres | |
| CockroachDB |
It is possible to test a individual backend only to speed up development roundtrip.
backend can be one ofMemory,Postgres,Cockroach,Etcd,Redis, andMongoDB.
BACKEND=backend maketestAbout
golang grpc service and library for ip address management
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.