diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2024-10-06 11:45:14 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2024-10-06 11:45:14 +0200 |
commit | 4aa11423038f181c3ad537a5172ef4075c236d00 (patch) | |
tree | fe5723feeeaa1e8d3c0d87b6e6b43f769cd974e7 | |
parent | 4bacde703ea23ff9b7313b9dc6049c19ffce67f2 (diff) | |
download | infra-4aa11423038f181c3ad537a5172ef4075c236d00.tar.gz infra-4aa11423038f181c3ad537a5172ef4075c236d00.tar.bz2 infra-4aa11423038f181c3ad537a5172ef4075c236d00.tar.xz infra-4aa11423038f181c3ad537a5172ef4075c236d00.zip |
ipam util
-rw-r--r-- | ansible/group_vars/all/ipam.yml | 12 | ||||
-rw-r--r-- | utils/go.mod | 5 | ||||
-rw-r--r-- | utils/go.sum | 4 | ||||
-rw-r--r-- | utils/main.go | 160 | ||||
-rw-r--r-- | utils/yaml_ipam/yaml_ipam.go | 26 |
5 files changed, 201 insertions, 6 deletions
diff --git a/ansible/group_vars/all/ipam.yml b/ansible/group_vars/all/ipam.yml index f3f75ac..aa9da27 100644 --- a/ansible/group_vars/all/ipam.yml +++ b/ansible/group_vars/all/ipam.yml @@ -15,25 +15,25 @@ ipam6: node1_dn42: range: "fdb1:4242:3538:2002::/64" hosts: - node1: "fdb1:4242:3538:2002::/64" + node1: "fdb1:4242:3538:2002::ffff" node2_dn42: range: "fdb1:4242:3538:2003::/64" hosts: - node2: "fdb1:4242:3538:2003::/64" + node2: "fdb1:4242:3538:2003::ffff" knot_dn42: range: "fdb1:4242:3538:2004::/64" hosts: - knot: "fdb1:4242:3538:2004::ffff/64" + knot: "fdb1:4242:3538:2004::ffff" coregonus_dn42: range: "fdb1:4242:3538:2005::/64" hosts: - coregonus-ix: "fdb1:4242:3538:2005::ffff/64" + coregonus-ix: "fdb1:4242:3538:2005::ffff" coregonus_docker: range: "fdb1:4242:3538:2005:df01:676a:ec28:0a00/120" kv24_dn42: range: "fdb1:4242:3538:2006::/64" hosts: - kv24ix: "fdb1:4242:3538:2006::ffff/64" + kv24ix: "fdb1:4242:3538:2006::ffff" hash_dn42: range: "fdb1:4242:3538:2007::/64" hosts: @@ -43,7 +43,7 @@ ipam6: lhn2_dn42: range: "fdb1:4242:3538:2008::/64" hosts: - lhn2pi: "fdb1:4242:3538:2008::ffff/64" + lhn2pi: "fdb1:4242:3538:2008::ffff" conflatorio: "fdb1:4242:3538:2008:8042:32ff:fe0c:7161" danneri: "fdb1:4242:3538:2008:9422:d355:95b7:f170" diff --git a/utils/go.mod b/utils/go.mod new file mode 100644 index 0000000..0090185 --- /dev/null +++ b/utils/go.mod @@ -0,0 +1,5 @@ +module utils + +go 1.23 + +require gopkg.in/yaml.v3 v3.0.1 diff --git a/utils/go.sum b/utils/go.sum new file mode 100644 index 0000000..a62c313 --- /dev/null +++ b/utils/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/utils/main.go b/utils/main.go new file mode 100644 index 0000000..db27e9c --- /dev/null +++ b/utils/main.go @@ -0,0 +1,160 @@ +package main + +import ( + "fmt" + "log" + "net/netip" + "os" + "utils/yaml_ipam" +) + +func main() { + err := work() + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Error reading file: %v\n", err) + os.Exit(1) + } +} + +func work() error { + ipamYaml := "../ansible/group_vars/all/ipam.yml" + bs, err := os.ReadFile(ipamYaml) + if err != nil { + return err + } + + ipam, err := loadIpam(bs) + if err != nil { + return err + } + + fmt.Printf("digraph {\n") + //fmt.Printf(" layout=dot\n") + //fmt.Printf(" layout=twopi\n") + fmt.Printf(" layout=circo\n") + //fmt.Printf(" ranksep=3\n") + //fmt.Printf(" ratio=auto\n") + //fmt.Printf(" rankdir=LR\n") + //fmt.Printf(" rankdir=RL\n") + //fmt.Printf(" rankdir=TB\n") + fmt.Printf("\n") + fmt.Printf(" # Nodes\n") + for _, n := range ipam.networks { + fmt.Printf(" %s [ label = \"%s\\n%s\"];\n", n.name, n.name, n.prefix) + } + for _, n := range ipam.FindRoots() { + fmt.Printf(" %s [ root = true ];\n", n.name) + } + + fmt.Printf("\n") + fmt.Printf(" # Relationships\n") + for _, n := range ipam.networks { + for _, c := range ipam.networks { + if c.parent == n { + fmt.Printf(" %s -> %s;\n", n.name, c.name) + } + } + } + fmt.Printf("}\n") + + return nil +} + +func loadIpam(bs []byte) (*Ipam, error) { + parsed, err := yaml_ipam.Parse(bs) + if err != nil { + return nil, err + } + + ipam_, err := processNetworks(parsed.Ipam6.Networks) + if err != nil { + return nil, err + } + + ipam_.ResolveParents() + + return ipam_, nil +} + +type Ipam struct { + networks []*Network +} + +func (ipam *Ipam) ResolveParents() { + for _, n := range ipam.networks { + log.Printf("network %s/%s", n.name, n.prefix) + for _, p := range ipam.networks { + if n == p { + continue + } + //log.Printf("candidate %s/%s", p.name, p.prefix) + if p.prefix.Contains(n.prefix.Addr()) { + if n.parent == nil { + log.Printf("found parent %s/%s", p.name, p.prefix) + n.parent = p + } else { + if n.parent.prefix.Contains(p.prefix.Addr()) { + log.Printf("found better parent %s/%s", p.name, p.prefix) + n.parent = p + } + } + } + } + } + + return +} + +func (ipam *Ipam) FindRoots() []*Network { + var ns []*Network + + for _, n := range ipam.networks { + if n.parent == nil { + ns = append(ns, n) + } + } + + return ns +} + +type Network struct { + name string + parent *Network + prefix netip.Prefix + hosts []networkHost +} + +type networkHost struct { + name string + address netip.Addr +} + +func processNetworks(networks map[string]yaml_ipam.Network6Yaml) (*Ipam, error) { + var ns []*Network + + for name, net := range networks { + log.Printf("Processing net %v\net", name) + prefix, err := netip.ParsePrefix(net.Range) + if err != nil { + return nil, fmt.Errorf("error parsing net range: %v\net", err) + } + log.Printf("prefix: %s", prefix.String()) + + n := Network{name: name, prefix: prefix} + for hostname, a := range net.Hosts { + addr, err := netip.ParseAddr(a) + if err != nil { + return nil, fmt.Errorf("network: %s, unable to parse host address %s\net", n.name, a) + } + + n.hosts = append(n.hosts, networkHost{ + name: hostname, + address: addr, + }) + } + + ns = append(ns, &n) + } + + return &Ipam{networks: ns}, nil +} diff --git a/utils/yaml_ipam/yaml_ipam.go b/utils/yaml_ipam/yaml_ipam.go new file mode 100644 index 0000000..ff65155 --- /dev/null +++ b/utils/yaml_ipam/yaml_ipam.go @@ -0,0 +1,26 @@ +package yaml_ipam + +import "gopkg.in/yaml.v3" + +type Ipam struct { + Ipam6 Ipam6 `yaml:"ipam6"` +} + +type Ipam6 struct { + Networks map[string]Network6Yaml `yaml:"networks"` +} + +type Network6Yaml struct { + Range string `yaml:"range"` + Hosts map[string]string `yaml:"hosts"` +} + +func Parse(bs []byte) (Ipam, error) { + var ipam Ipam + err := yaml.Unmarshal(bs, &ipam) + if err != nil { + return Ipam{}, err + } + + return ipam, nil +} |