Skip to content

golang library for ip address management

License

Notifications You must be signed in to change notification settings

dawenga/go-ipam

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-ipam

Actions GoDoc Go Report Card codecov License

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.

IP

Most obvious this library is all about IP management. The main purpose is to acquire and release an IP, or a bunch of IP's from prefixes.

Prefix

A prefix is a network with IP and mask, typically in the form of 192.168.0.0/24. To be able to manage IPs you have to create a prefix first.

Library Example usage:

package main

import (
    "fmt"
    "time"
    goipam "github.com/metal-stack/go-ipam"
)

func main() {
    // create a ipamer with in memory storage
    ipam := goipam.New()


    bgCtx := context.Background()
    // Optional with Namespace
    ctx := goipam.NewContextWithNamespace(bgCtx, "tenant-a")

    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()
    prefix, err := ipam.NewPrefix(ctx, "192.168.0.0/24")
    if err != nil {
        panic(err)
    }

    ip, err := ipam.AcquireIP(ctx, prefix.Cidr)
    if err != nil {
        panic(err)
    }
    fmt.Printf("got IP: %s\n", ip.IP)

    prefix, err = ipam.ReleaseIP(ctx, ip)
    if err != nil {
        panic(err)
    }
    fmt.Printf("IP: %s released.\n", ip.IP)

    // Now a IPv6 Super Prefix with Child Prefixes
    prefix, err = ipam.NewPrefix(ctx, "2001:aabb::/48")
    if err != nil {
        panic(err)
    }
    cp1, err := ipam.AcquireChildPrefix(ctx, prefix.Cidr, 64)
    if err != nil {
        panic(err)
    }
    fmt.Printf("got Prefix: %s\n", cp1)
    cp2, err := ipam.AcquireChildPrefix(ctx, prefix.Cidr, 72)
    if err != nil {
        panic(err)
    }
    fmt.Printf("got Prefix: %s\n", cp2)
    ip21, err := ipam.AcquireIP(ctx, cp2.Cidr)
    if err != nil {
        panic(err)
    }
    fmt.Printf("got IP: %s\n", ip21.IP)
}

GRPC Service

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 main

import (
    "http"

    "github.com/bufbuild/connect-go"
    v1 "github.com/metal-stack/go-ipam/api/v1"
    "github.com/metal-stack/go-ipam/api/v1/apiv1connect"
)
func main() {

    c := apiv1connect.NewIpamServiceClient(
            http.DefaultClient,
            "http://localhost:9090",
            connect.WithGRPC(),
    )

    bgCtx := context.Background()

    // Optional with Namespace
    ctx := goipam.NewContextWithNamespace(bgCtx, "tenant-a")

    result, err := c.CreatePrefix(ctx, connect.NewRequest(&v1.CreatePrefixRequest{Cidr: "192.168.0.0/16",}))
    if err != nil {
        panic(err)
    }
    fmt.Println("Prefix:%q created", result.Msg.GetPrefix().GetCidr())
}

GRPC client

There is also a cli 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

Supported Databases & Performance

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:16-alpine
  • cockroach:v23.1.0
  • redis:7.2-alpine
  • keydb:alpine_x86_64_v6.3.1
  • etcd:v3.5.9
  • mongodb:7

Database Version Compatability

Database Details
KeyDB
Redis
MongoDB mongodb-go compatibility
Etcd
Postgres
CockroachDB

Testing individual Backends

It is possible to test a individual backend only to speed up development roundtrip.

backend can be one of Memory, Postgres, Cockroach, Etcd, Redis, and MongoDB.

BACKEND=backend make test

About

golang library for ip address management

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 98.1%
  • Makefile 1.8%
  • Dockerfile 0.1%