From dc74eac02b0cd1df0078b1c113fc3e219279a9ed Mon Sep 17 00:00:00 2001 From: glattercj Date: Sun, 1 Sep 2024 11:51:18 -0600 Subject: [PATCH] feat: add new helper funcs spec --- src/go/types/interfaces/scenario.go | 4 ++ src/go/types/interfaces/topology.go | 47 +++++++++++++++++++++++ src/go/types/version/v0/network.go | 20 ++++++++++ src/go/types/version/v0/node.go | 38 +++++++++++++++++++ src/go/types/version/v0/topology.go | 15 ++++++++ src/go/types/version/v1/network.go | 20 ++++++++++ src/go/types/version/v1/node.go | 59 +++++++++++++++++++++++++++++ src/go/types/version/v1/topology.go | 15 ++++++++ src/go/types/version/v2/scenario.go | 24 ++++++++++++ 9 files changed, 242 insertions(+) diff --git a/src/go/types/interfaces/scenario.go b/src/go/types/interfaces/scenario.go index df9a5678..aa98935a 100644 --- a/src/go/types/interfaces/scenario.go +++ b/src/go/types/interfaces/scenario.go @@ -3,6 +3,8 @@ package ifaces type ScenarioSpec interface { Apps() []ScenarioApp App(string) ScenarioApp + + AddApp(string) ScenarioApp } type ScenarioApp interface { @@ -17,6 +19,7 @@ type ScenarioApp interface { SetAssetDir(string) SetMetadata(map[string]any) SetHosts([]ScenarioAppHost) + AddHost(string) ScenarioAppHost SetRunPeriodically(string) SetDisabled(bool) @@ -28,5 +31,6 @@ type ScenarioAppHost interface { Hostname() string Metadata() map[string]any + SetMetadata(map[string]any) ParseMetadata(any) error } diff --git a/src/go/types/interfaces/topology.go b/src/go/types/interfaces/topology.go index e801506b..f41e2379 100644 --- a/src/go/types/interfaces/topology.go +++ b/src/go/types/interfaces/topology.go @@ -10,6 +10,7 @@ type TopologySpec interface { FindNodeByName(string) NodeSpec FindNodesWithLabels(...string) []NodeSpec FindDelayedNodes() []NodeSpec + FindNodesWithVLAN(string) []NodeSpec AddNode(string, string) NodeSpec RemoveNode(string) @@ -35,11 +36,55 @@ type NodeSpec interface { External() bool SetInjections([]NodeInjection) + SetType(string) + AddAnnotation(string, interface{}) + AddTimerDelay(delay string) + AddUserDelay(delay bool) + AddC2Delay(hostname string, useuuid bool) AddLabel(string, string) AddHardware(string, int, int) NodeHardware AddNetworkInterface(string, string, string) NodeNetworkInterface AddNetworkRoute(string, string, int) + // Add NAT section to Node Network + // + // Example code: + // + // newNat := map[string][]string{ + // "eth0": {"eth1"}, + // } + // nats := []map[string][]string{} + // nats = append(nats, newNat) + // node.AddNetworkNAT(nats) + // + // Example result: + // + // nat: + // - in: + // - eth1 + // out: eth0 + AddNetworkNAT(nats []map[string][]string) + // Add OSPF section to Node Network + // + // Example code: + // + // area := map[int][]string{ + // 0: {"75.75.0.0/16"}, + // } + // node.AddNetworkOSPF("75.75.75.5", 60, 10, 5, area) + // + // Example result: + // + // ospf: + // router_id: 75.75.75.5 + // dead_interval: 60 + // hello_interval: 10 + // retransmission_interval: 5 + // areas: + // - area_id: 0 + // area_networks: + // - network: 75.75.0.0/16 + AddNetworkOSPF(routerID string, dead, hello, retrans int, areas map[int][]string) AddInject(string, string, string, string) SetAdvanced(map[string]string) @@ -96,6 +141,8 @@ type NodeNetwork interface { AddRuleset(NodeNetworkRuleset) InterfaceAddress(string) string + InterfaceVLAN(string) string + InterfaceMask(string) int } type NodeNetworkInterface interface { diff --git a/src/go/types/version/v0/network.go b/src/go/types/version/v0/network.go index c3e21321..6711c79a 100644 --- a/src/go/types/version/v0/network.go +++ b/src/go/types/version/v0/network.go @@ -77,6 +77,26 @@ func (this *Network) InterfaceAddress(name string) string { return "" } +func (this *Network) InterfaceVLAN(vlan string) string { + for _, iface := range this.InterfacesF { + if iface.VLAN() == vlan { + return iface.NameF + } + } + + return "" +} + +func (this *Network) InterfaceMask(name string) int { + for _, iface := range this.InterfacesF { + if strings.EqualFold(iface.NameF, name) { + return iface.MaskF + } + } + + return 0 +} + type Interface struct { NameF string `json:"name" yaml:"name" structs:"name" mapstructure:"name"` TypeF string `json:"type" yaml:"type" structs:"type" mapstructure:"type"` diff --git a/src/go/types/version/v0/node.go b/src/go/types/version/v0/node.go index 2798f5a7..24ea5d02 100644 --- a/src/go/types/version/v0/node.go +++ b/src/go/types/version/v0/node.go @@ -85,6 +85,24 @@ func (this *Node) SetInjections(injections []ifaces.NodeInjection) { this.InjectionsF = injects } +func (this *Node) SetType(t string) { + this.TypeF = t +} + +func (this *Node) AddAnnotation(k string, i interface{}) { + if this.AnnotationsF == nil { + this.AnnotationsF = make(map[string]interface{}) + } + + this.AnnotationsF[k] = i +} + +func (this *Node) AddTimerDelay(string) {} + +func (this *Node) AddUserDelay(bool) {} + +func (this *Node) AddC2Delay(string, bool) {} + func (this *Node) AddLabel(k, v string) { this.LabelsF[k] = v } @@ -131,6 +149,26 @@ func (this *Node) AddNetworkRoute(dest, next string, cost int) { this.NetworkF.RoutesF = append(this.NetworkF.RoutesF, r) } +func (this *Node) AddNetworkNAT([]map[string][]string) {} + +func (this *Node) AddNetworkOSPF(routerID string, dead, hello, retrans int, areas map[int][]string) { + this.NetworkF.OSPFF = new(OSPF) + this.NetworkF.OSPFF.RouterIDF = routerID + this.NetworkF.OSPFF.DeadIntervalF = &dead + this.NetworkF.OSPFF.HelloIntervalF = &hello + this.NetworkF.OSPFF.RetransmissionIntervalF = &retrans + + for id, networks := range areas { + area := new(Area) + area.AreaIDF = &id + for _, net := range networks { + areaNetwork := AreaNetwork{NetworkF: net} + area.AreaNetworksF = append(area.AreaNetworksF, areaNetwork) + } + this.NetworkF.OSPFF.AreasF = append(this.NetworkF.OSPFF.AreasF, *area) + } +} + func (this *Node) AddInject(src, dst, perms, desc string) { this.InjectionsF = append(this.InjectionsF, &Injection{ SrcF: src, diff --git a/src/go/types/version/v0/topology.go b/src/go/types/version/v0/topology.go index 47ac3b08..560cb10a 100644 --- a/src/go/types/version/v0/topology.go +++ b/src/go/types/version/v0/topology.go @@ -94,6 +94,21 @@ func (TopologySpec) FindDelayedNodes() []ifaces.NodeSpec { return nil } +func (this TopologySpec) FindNodesWithVLAN(vlan string) []ifaces.NodeSpec { + var nodes []ifaces.NodeSpec + + for _, n := range this.NodesF { + for _, i := range n.NetworkF.InterfacesF { + if i.VLAN() == vlan { + nodes = append(nodes, n) + break + } + } + } + + return nodes +} + func (this *TopologySpec) AddNode(typ, hostname string) ifaces.NodeSpec { n := &Node{ TypeF: typ, diff --git a/src/go/types/version/v1/network.go b/src/go/types/version/v1/network.go index 48f89188..7635793b 100644 --- a/src/go/types/version/v1/network.go +++ b/src/go/types/version/v1/network.go @@ -110,6 +110,26 @@ func (this *Network) InterfaceAddress(name string) string { return "" } +func (this *Network) InterfaceVLAN(vlan string) string { + for _, iface := range this.InterfacesF { + if iface.VLAN() == vlan { + return iface.NameF + } + } + + return "" +} + +func (this *Network) InterfaceMask(name string) int { + for _, iface := range this.InterfacesF { + if strings.EqualFold(iface.NameF, name) { + return iface.MaskF + } + } + + return 0 +} + type Interface struct { NameF string `json:"name" yaml:"name" structs:"name" mapstructure:"name"` TypeF string `json:"type" yaml:"type" structs:"type" mapstructure:"type"` diff --git a/src/go/types/version/v1/node.go b/src/go/types/version/v1/node.go index d19ef391..2b8bc097 100644 --- a/src/go/types/version/v1/node.go +++ b/src/go/types/version/v1/node.go @@ -102,6 +102,34 @@ func (this *Node) SetInjections(injections []ifaces.NodeInjection) { this.InjectionsF = injects } +func (this *Node) SetType(t string) { + this.TypeF = t +} + +func (this *Node) AddAnnotation(k string, i interface{}) { + if this.AnnotationsF == nil { + this.AnnotationsF = make(map[string]interface{}) + } + + this.AnnotationsF[k] = i +} + +func (this *Node) AddTimerDelay(delay string) { + this.DelayF.TimerF = delay +} + +func (this *Node) AddUserDelay(delay bool) { + this.DelayF.UserF = delay +} + +func (this *Node) AddC2Delay(hostname string, useuuid bool) { + this.DelayF = new(Delay) + d := new(C2Delay) + d.HostnameF = hostname + d.UseUUIDF = useuuid + this.DelayF.C2F = append(this.DelayF.C2F, *d) +} + func (this *Node) AddLabel(k, v string) { if this.LabelsF == nil { this.LabelsF = make(map[string]string) @@ -152,6 +180,37 @@ func (this *Node) AddNetworkRoute(dest, next string, cost int) { this.NetworkF.RoutesF = append(this.NetworkF.RoutesF, r) } +func (this *Node) AddNetworkNAT(nats []map[string][]string) { + for _, nat := range nats { + n := new(NAT) + for out, ins := range nat { + n.OutF = out + for _, in := range ins { + n.InF = append(n.InF, in) + } + } + this.NetworkF.NATF = append(this.NetworkF.NATF, *n) + } +} + +func (this *Node) AddNetworkOSPF(routerID string, dead, hello, retrans int, areas map[int][]string) { + this.NetworkF.OSPFF = new(OSPF) + this.NetworkF.OSPFF.RouterIDF = routerID + this.NetworkF.OSPFF.DeadIntervalF = &dead + this.NetworkF.OSPFF.HelloIntervalF = &hello + this.NetworkF.OSPFF.RetransmissionIntervalF = &retrans + + for id, networks := range areas { + area := new(Area) + area.AreaIDF = &id + for _, net := range networks { + areaNetwork := AreaNetwork{NetworkF: net} + area.AreaNetworksF = append(area.AreaNetworksF, areaNetwork) + } + this.NetworkF.OSPFF.AreasF = append(this.NetworkF.OSPFF.AreasF, *area) + } +} + func (this *Node) AddInject(src, dst, perms, desc string) { if _, ok := this.LabelsF["disable-injects"]; ok { return diff --git a/src/go/types/version/v1/topology.go b/src/go/types/version/v1/topology.go index 9222d177..67ac8ec4 100644 --- a/src/go/types/version/v1/topology.go +++ b/src/go/types/version/v1/topology.go @@ -105,6 +105,21 @@ func (this TopologySpec) FindDelayedNodes() []ifaces.NodeSpec { return nodes } +func (this TopologySpec) FindNodesWithVLAN(vlan string) []ifaces.NodeSpec { + var nodes []ifaces.NodeSpec + + for _, n := range this.NodesF { + for _, i := range n.NetworkF.InterfacesF { + if i.VLAN() == vlan { + nodes = append(nodes, n) + break + } + } + } + + return nodes +} + func (this *TopologySpec) AddNode(typ, hostname string) ifaces.NodeSpec { n := &Node{ TypeF: typ, diff --git a/src/go/types/version/v2/scenario.go b/src/go/types/version/v2/scenario.go index 858dbc1f..8db662e1 100644 --- a/src/go/types/version/v2/scenario.go +++ b/src/go/types/version/v2/scenario.go @@ -39,6 +39,16 @@ func (this *ScenarioSpec) App(name string) ifaces.ScenarioApp { return nil } +func (this *ScenarioSpec) AddApp(name string) ifaces.ScenarioApp { + a := &ScenarioApp{ + NameF: name, + } + + this.AppsF = append(this.AppsF, a) + + return a +} + type ScenarioApp struct { NameF string `json:"name" yaml:"name" structs:"name" mapstructure:"name"` FromScenarioF string `json:"fromScenario,omitempty" yaml:"fromScenario,omitempty" structs:"fromScenario" mapstructure:"fromScenario"` @@ -101,6 +111,16 @@ func (this *ScenarioApp) SetHosts(hosts []ifaces.ScenarioAppHost) { this.HostsF = h } +func (this *ScenarioApp) AddHost(hostname string) ifaces.ScenarioAppHost { + h := &ScenarioAppHost{ + HostnameF: hostname, + } + + this.HostsF = append(this.HostsF, h) + + return h +} + func (this *ScenarioApp) SetRunPeriodically(d string) { this.RunPeriodicallyF = d } @@ -148,6 +168,10 @@ func (this ScenarioAppHost) Metadata() map[string]any { return this.MetadataF } +func (this *ScenarioAppHost) SetMetadata(md map[string]interface{}) { + this.MetadataF = md +} + func (this ScenarioAppHost) ParseMetadata(md any) error { if this.MetadataF == nil { return fmt.Errorf("missing metadata for host %s", this.HostnameF)