Skip to content

Commit

Permalink
Add OpenConfig interface to oc3 example
Browse files Browse the repository at this point in the history
  • Loading branch information
nleiva committed Aug 28, 2017
1 parent a3ac2c3 commit b8e81b9
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 17 deletions.
78 changes: 61 additions & 17 deletions example/configvalidateoc3/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/*
1. Configures a Streaming Telemetry subscription using an OpenConfig model template.
2. Configures a BGP neighbor using an OpenConfig model template.
3. Subscribes to the Telemetry stream to learn about BGP neighbor status.
2. Configures an Interface using an OpenConfig model template.
3. Configures a BGP neighbor using an OpenConfig model template.
4. Subscribes to the Telemetry stream to learn about BGP neighbor status.
*/

package main
Expand All @@ -13,6 +14,7 @@ import (
"fmt"
"log"
"math/rand"
"net"
"os"
"os/signal"
"time"
Expand All @@ -24,13 +26,14 @@ import (

func main() {
// OpenConfig YANG templates
bgpt := flag.String("bt", "../input/template/oc-bgp.json", "BGP Config Template")
telet := flag.String("tt", "../input/template/oc-telemetry.json", "Telemetry Config Template")
intt := flag.String("it", "../input/template/oc-interface.json", "Interface Config Template")
bgpt := flag.String("bt", "../input/template/oc-bgp.json", "BGP Config Template")
flag.Parse()

// Determine the ID for first the transaction.
r := rand.New(rand.NewSource(time.Now().UnixNano()))
id := r.Int63n(10000)
ra := rand.New(rand.NewSource(time.Now().UnixNano()))
id := ra.Int63n(10000)

// Manually specify target parameters.
router, err := xr.BuildRouter(
Expand All @@ -44,10 +47,16 @@ func main() {
log.Fatalf("target parameters are incorrect: %s", err)
}

// Extract the IP address
r, err := net.ResolveTCPAddr("tcp", router.Host)
if err != nil {
log.Fatalf("Incorrect IP address: %v", err)
}

// Connect to the router
conn, ctx, err := xr.Connect(*router)
if err != nil {
log.Fatalf("could not setup a client connection to %s, %v", router.Host, err)
log.Fatalf("could not setup a client connection to %s, %v", r.IP, err)
}
defer conn.Close()

Expand All @@ -72,16 +81,51 @@ func main() {
log.Fatalf("Telemetry, %s", err)
}

// Applly Telemetry config
// Apply Telemetry config
_, err = xr.MergeConfig(ctx, conn, teleConfig, id)
if err != nil {
log.Fatalf("failed to config %s: %v\n", router.Host, err)
log.Fatalf("failed to config %s: %v\n", r.IP, err)
} else {
fmt.Printf("\n1)\n%sTelemetry%s config applied on %s (Request ID: %v)\n", blue, white, r.IP, id)
}
id++

// Pause
fmt.Print("Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

// Generate the Interface config.
// At present, ethernet-like media are identified by the value ethernetCsmacd(6).
// The index of the subinterface, or logical interface number. On systems with no
// support for subinterfaces, or not using subinterfaces, this value should default
// to 0, i.e., the default subinterface.
ic := new(InterfaceConfig)
ic.Name = "HundredGigE0/0/0/1"
ic.Type = "iana-if-type:ethernetCsmacd"
ic.MTU = 9192
ic.Description = "Peer Link"
ic.Enabled = true
ic.AutoNegotiate = false
ic.Index = 0
// Change to net.IP
ic.Address = "2001:db8:cafe::1"
ic.PrefixLength = 64

intConfig, err := templateProcess(*intt, ic)
if err != nil {
log.Fatalf("Interface, %s", err)
}

// Apply Interface config
_, err = xr.MergeConfig(ctx, conn, intConfig, id)
if err != nil {
log.Fatalf("failed to config %s: %v\n", r.IP, err)
} else {
fmt.Printf("\n1)\nTelemetry config applied on %s (Request ID: %v)\n", router.Host, id)
fmt.Printf("\n2)\n%sInterface%s config applied on %s (Request ID: %v)\n", blue, white, r.IP, id)
}
id++

// First Pause
// Pause
fmt.Print("Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

Expand All @@ -101,12 +145,12 @@ func main() {
// Apply the BGP template+parameters to the target
_, err = xr.MergeConfig(ctx, conn, bgpConfig, id)
if err != nil {
log.Fatalf("failed to config %s: %v\n", router.Host, err)
log.Fatalf("failed to config %s: %v\n", r.IP, err)
} else {
fmt.Printf("\n2)\nBGP Config applied on %s (Request ID: %v)\n", router.Host, id)
fmt.Printf("\n3)\n%sBGP%s Config applied on %s (Request ID: %v)\n", blue, white, r.IP, id)
}

// Second Pause
// Pause
fmt.Print("Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

Expand All @@ -121,7 +165,7 @@ func main() {
go func() {
select {
case <-c:
fmt.Printf("\nmanually cancelled the session to %v\n\n", router.Host)
fmt.Printf("\nmanually cancelled the session to %v\n\n", r.IP)
cancel()
return
case <-ctx.Done():
Expand All @@ -131,11 +175,11 @@ func main() {
return
case err = <-ech:
// Session canceled: "context canceled"
fmt.Printf("\ngRPC session to %v failed: %v\n\n", router.Host, err.Error())
fmt.Printf("\ngRPC session to %v failed: %v\n\n", r.IP, err.Error())
return
}
}()
fmt.Printf("\n3)\nReceiving Telemetry from %s ->\n\n", router.Host)
fmt.Printf("\n4)\nReceiving %sTelemetry%s from %s ->\n\n", blue, white, r.IP)

for tele := range ch {
message := new(telemetry.Telemetry)
Expand Down Expand Up @@ -188,7 +232,7 @@ func decodeKV(f *telemetry.TelemetryField, indent string, peer string, ok *bool)
t := time.Now()
fmt.Printf("\rNeighbor: %s, Time: %v, State: %s%s%s ", peer, t.Format("15:04:05"), color, state, white)
if state == "bgp-st-estab" {
fmt.Printf("\n\nSession %sOK%s !! \n\n", green, white)
fmt.Printf("\n\n\n Session \u2705 \n\n\n")
os.Exit(0)
}
}
Expand Down
65 changes: 65 additions & 0 deletions example/configvalidateoc3/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,66 @@ type TelemetryConfig struct {
Subscription
}

/*
Borrowing some definitions from:
- openconfig-interfaces:
https://github.com/openconfig/public/blob/master/release/models/interfaces/openconfig-interfaces.yang
- openconfig-if-ethernet:
https://github.com/openconfig/public/blob/master/release/models/interfaces/openconfig-if-ethernet.yang
- openconfig-if-ip:
https://github.com/openconfig/public/blob/master/release/models/interfaces/openconfig-if-ip.yang
- A YANG Data Model for Interface Management (RFC 7223): https://tools.ietf.org/html/rfc7223
- Definitions of Managed Objects for the Ethernet-like Interface Types (RFC 3635):
https://tools.ietf.org/html/rfc3635
TODO: Take a look at:
https://github.com/openconfig/ygot#validating-the-struct-contents
*/

// InterfaceConfig represents the configuration of a physical interfaces
// and subinterfaces.
// At present, ethernet-like media are identified by the value ethernetCsmacd(6) of the ifType
// object in the Interfaces MIB [RFC2863]
type InterfaceConfig struct {
Name string
Description string
Enabled bool
Physical
Ethernet
SubInterface
}

// Physical defines configuration data for physical interfaces.
type Physical struct {
Type string
MTU uint16
}

// Ethernet defines configuration items for Ethernet interfaces.
type Ethernet struct {
MACAddress string
AutoNegotiate bool
DuplexMode string
PortSpeed string
}

// SubInterface defines data for logical interfaces associated with a given interface.
type SubInterface struct {
Index uint32
IPv6
}

// IPv6 defines configuration and state for IPv6 interfaces.
type IPv6 struct {
Address string
PrefixLength uint8
}

// templateProcess reads the template from a file and apply the parameters
// provided through an interface.
func templateProcess(file string, p interface{}) (out string, err error) {
Expand All @@ -69,3 +129,8 @@ func templateProcess(file string, p interface{}) (out string, err error) {
}
return buf.String(), nil
}

// ⍻ NOT CHECK MARK (U+237B) e28dbb
// ✅ WHITE HEAVY CHECK MARK (U+2705) e29c85
// ✓ CHECK MARK (U+2713) e29c93
// ✔ HEAVY CHECK MARK (U+2714) e29c94
82 changes: 82 additions & 0 deletions example/configvalidateoc3/peeringdb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

// PeeringDB, Comcast example: https://beta.peeringdb.com/api/net?asn=7922

/*
{"meta": {}, "data": [{"id": 822, "org_id": 1061, "name": "Comcast", "aka": "Comcast Backbone - 7922",
"website": "", "asn": 7922, "looking_glass": "", "route_server": "telnet://route-server.newyork.ny.ibone.comcast.net",
"irr_as_set": "AS-COMCAST-IBONE", "info_type": "Cable/DSL/ISP", "info_prefixes4": 14000, "info_prefixes6": 600,
"info_traffic": "1 Tbps+", "info_ratio": "Balanced", "info_scope": "North America", "info_unicast": true,
"info_multicast": false, "info_ipv6": true, "notes": "peering@comcast.com is the best email address to send requests
for IPv6 & settled peering after reviewing http://www.comcast.com/peering. It is not a 24x7 operations contact and
should not be assumed appropriate for that purpose.\n\nWe do not offer peering, paid or otherwise, on the shared fabric
public switches at any IX.\n\nREMINDER: Max prefix settings:\nIPv4 set to 30K\nIPv6 set to 2K\n\nPlease ensure that
you are set up to accept these prefixes from AS7922 for server l.root-servers.net -\n199.7.83.0/24 & 2001:500:3::/48",
"policy_url": "http://www.comcast.com/peering", "policy_general": "Selective", "policy_locations": "Required - US",
"policy_ratio": true, "policy_contracts": "Required", "created": "2010-05-24T13:13:54Z", "updated": "2017-03-28T16:08:20Z",
"status": "ok"}]}
*/

// NetworkSerializer is the https://peeringdb.com/apidocs/#!/net/Network_list data model
type NetworkSerializer struct {
ID int `json:"id"`
OrgID int `json:"org_id"`
Org string `json:"org"`
Name string `json:"name"`
Aka string `json:"aka"`
Website string `json:"website"`
ASN int `json:"asn"`
LookingGlass string `json:"looking_glass"`
RouteServer string `json:"route_server"`
IrrAsSet string `json:"irr_as_set"`
InfoType string `json:"info_type"`
InfoPrefixes4 int `json:"info_prefixes4"`
InfoPrefixes6 int `json:"info_prefixes6"`
InfoTraffic string `json:"info_traffic"`
InfoRatio string `json:"info_ratio"`
InfoScope string `json:"info_scope"`
InfoUnicast bool `json:"info_unicast"`
InfoMulticast bool `json:"info_multicast"`
InfoIPv6 bool `json:"info_ipv6"`
Notes string `json:"notes"`
PolicyURL string `json:"policy_url"`
PolicyGeneral string `json:"policy_general"`
PolicyLocations string `json:"policy_locations"`
PolicyRatio bool `json:"policy_ratio"`
PolicyContracts string `json:"policy_contracts"`
NetfacSet map[string]string `json:"netfac_set"`
NetixlanSet map[string]string `json:"netixlan_set"`
PocSet map[string]string `json:"poc_set"`
Created string `json:"created"`
Updated string `json:"updated"`
Status string `json:"status"`
}

// NetworkSerializer is the https://peeringdb.com/apidocs/#!/net/Network_list data model
//
// InfoType:
// ['' or 'Not Disclosed' or 'NSP' or 'Content' or 'Cable/DSL/ISP' or 'Enterprise'
// or 'Educational/Research' or 'Non-Profit' or 'Route Server']
// InfoTraffic:
// ['' or '0-20 Mbps' or '20-100Mbps' or '100-1000Mbps' or '1-5Gbps' or '5-10Gbps'
// or '10-20Gbps' or '20-50 Gbps' or '50-100 Gbps' or '100+ Gbps' or '100-200 Gbps'
// or '200-300 Gbps' or '300-500 Gbps' or '500-1000 Gbps' or '1 Tbps+' or '10 Tbps+']
// InfoRatio:
// ['' or 'Not Disclosed' or 'Heavy Outbound' or 'Mostly Outbound' or 'Balanced'
// or 'Mostly Inbound' or 'Heavy Inbound']
// InfoScope:
// ['' or 'Not Disclosed' or 'Regional' or 'North America' or 'Asia Pacific' or 'Europe'
// or 'South America' or 'Africa' or 'Australia' or 'Middle East' or 'Global']
// PolicyGeneral:
// ['Open' or 'Selective' or 'Restrictive' or 'No']
// PolicyLocations:
// ['Not Required' or 'Preferred' or 'Required - US' or 'Required - EU' or 'Required - International']
// PolicyContracts:
// ['Not Required' or 'Private Only' or 'Required']
// NetfacSet:
// (array[NetworkFacilitySerializer])
// NetixlanSet:
// (array[NetworkIXLanSerializer])
// PocSet:
// (array[NetworkContactSerializer])
//
41 changes: 41 additions & 0 deletions example/input/template/oc-interface.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{ "openconfig-interfaces:interfaces": {
"interface": [
{
"name": "{{.Name}}",
"config": {
"name": "{{.Name}}",
"type": "{{.Type}}",
"enabled": {{.Enabled}},
"description": "{{.Description}}",
"mtu": {{.MTU}}
},
"openconfig-if-ethernet:ethernet": {
"config": {
"auto-negotiate": {{.AutoNegotiate}}
}
},
"subinterfaces": {
"subinterface": [
{
"index": {{.Index}},
"openconfig-if-ip:ipv6": {
"addresses": {
"address": [
{
"ip": "{{.Address}}",
"config": {
"ip": "{{.Address}}",
"prefix-length": {{.PrefixLength}}
}
}
]
}
}
}
]
}
}
]
}
}

0 comments on commit b8e81b9

Please sign in to comment.