├── Chapter04 ├── Go │ ├── Adelaide_router_config.txt │ ├── Brisbane_router_config.txt │ ├── README.md │ ├── Sydney_router_config.txt │ ├── cisco_template_go.txt │ ├── config_render.go │ ├── go.mod │ ├── go.sum │ └── router_definitions.yaml └── Python │ ├── Adelaide_router_config.txt │ ├── Brisbane_router_config.txt │ ├── README.md │ ├── Sydney_router_config.txt │ ├── cisco_template_python.txt │ ├── config_render.py │ └── router_definitions.yaml ├── Chapter06 ├── Device-Emulator │ └── README.md ├── Go │ ├── README.md │ ├── go-gomiko-example.go │ ├── go.sum │ ├── gosnmp-example.go │ ├── scrapligo-example.go │ ├── ssh-example.go │ └── vssh-example.go └── Python │ ├── README.md │ ├── async-example.py │ ├── netmiko-example.py │ ├── paramiko-example.py │ ├── pysnmp-example.py │ └── scrapli-example.py ├── Chapter07 ├── Go │ ├── division-by-zero-panic-recover.go │ ├── division-by-zero-panic.go │ ├── error-library-error-division.go │ ├── error-library-fmt-division.go │ ├── go.mod │ ├── go.sum │ ├── logrus-logging.go │ ├── move-file-example.go │ ├── one.txt │ ├── panic-example-with-defer.go │ ├── panic-example.go │ ├── standard-logging-5-sev-levels.go │ └── standard-logging.go └── Python │ ├── catch-else-finally-division-by-zero.py │ ├── catching-division-by-zero-exception.py │ ├── division-by-zero-exception.py │ ├── logru-logging.py │ └── standard-logging.py ├── Chapter08 ├── Go │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── goroutine-icmp-probe-wg-sync.go │ ├── goroutine-icmp-probe.go │ └── parallelism.go ├── Python │ ├── README.md │ ├── asyncio-example-fixed.py │ ├── asyncio-example.py │ ├── multiple-pyping-example.py │ ├── performance-asyncio-threads-process.py │ ├── performance-thread-process-example.py │ ├── single-ping-example.py │ ├── single-pyping-example.py │ └── threads-pyping-example.py └── probe-service │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yaml │ ├── go.mod │ ├── go.sum │ └── icmp-probe-service.go ├── Chapter09 ├── AI │ └── Example-using-ChatGPT.mht └── NetworkX │ ├── .ipynb_checkpoints │ └── example-checkpoint.ipynb │ ├── example.ipynb │ ├── load_topology.py │ └── topology.yaml ├── Chapter10 └── NetworkLab │ ├── AUTOMATION.md │ └── README.md ├── LICENSE └── README.md /Chapter04/Go/Adelaide_router_config.txt: -------------------------------------------------------------------------------- 1 | hostname Adelaide 2 | ! 3 | interface Loopback100 4 | description Adelaide router loopback 5 | ip address 100.100.100.13 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to Melbourne router G0/1 9 | ! 10 | interface GigabitEthernet1/0.113 11 | description Access to Melbourne 12 | encapsulation dot1Q 113 13 | ip address 100.0.113.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.13 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Go/Brisbane_router_config.txt: -------------------------------------------------------------------------------- 1 | hostname Brisbane 2 | ! 3 | interface Loopback100 4 | description Brisbane router loopback 5 | ip address 100.100.100.12 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to Melbourne router G0/1 9 | ! 10 | interface GigabitEthernet1/0.112 11 | description Access to Melbourne 12 | encapsulation dot1Q 112 13 | ip address 100.0.112.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.12 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Go/README.md: -------------------------------------------------------------------------------- 1 | ## Configuration render for Go 2 | 3 | ### How to run: 4 | 5 | `go run config_render.go` 6 | -------------------------------------------------------------------------------- /Chapter04/Go/Sydney_router_config.txt: -------------------------------------------------------------------------------- 1 | hostname Sydney 2 | ! 3 | interface Loopback100 4 | description Sydney router loopback 5 | ip address 100.100.100.11 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to Melbourne router G0/1 9 | ! 10 | interface GigabitEthernet1/0.111 11 | description Access to Melbourne 12 | encapsulation dot1Q 111 13 | ip address 100.0.111.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.11 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Go/cisco_template_go.txt: -------------------------------------------------------------------------------- 1 | hostname {{.Name}} 2 | ! 3 | interface Loopback100 4 | description {{.Name}} router loopback 5 | ip address 100.100.100.{{.Id}} 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to {{.Toname}} router G0/1 9 | ! 10 | interface GigabitEthernet1/0.1{{.Id}} 11 | description Access to {{.Toname}} 12 | encapsulation dot1Q 1{{.Id}} 13 | ip address 100.0.1{{.Id}}.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.{{.Id}} 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Go/config_render.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "text/template" 7 | 8 | "gopkg.in/yaml.v3" 9 | ) 10 | 11 | type Router struct { 12 | Id int `yaml:"id"` 13 | Name string `yaml:"name"` 14 | Toname string `yaml:"to_name"` 15 | } 16 | 17 | type RouterList []Router 18 | 19 | func check(e error) { 20 | if e != nil { 21 | panic(e) 22 | } 23 | } 24 | 25 | func main() { 26 | var routers RouterList 27 | 28 | yamlFile, err := ioutil.ReadFile("router_definitions.yaml") 29 | check(err) 30 | 31 | err = yaml.Unmarshal(yamlFile, &routers) 32 | check(err) 33 | 34 | templateFile, err := ioutil.ReadFile("cisco_template_go.txt") 35 | check(err) 36 | 37 | for _, router := range routers { 38 | 39 | outFile, err := os.Create(router.Name + "_router_config.txt") 40 | check(err) 41 | 42 | tmpl, err := template.New("render").Parse(string(templateFile)) 43 | check(err) 44 | 45 | err = tmpl.Execute(outFile, router) 46 | check(err) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Chapter04/Go/go.mod: -------------------------------------------------------------------------------- 1 | module Go 2 | 3 | go 1.18 4 | 5 | require gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 6 | -------------------------------------------------------------------------------- /Chapter04/Go/go.sum: -------------------------------------------------------------------------------- 1 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 2 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 3 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 4 | -------------------------------------------------------------------------------- /Chapter04/Go/router_definitions.yaml: -------------------------------------------------------------------------------- 1 | - id: 11 2 | name: Sydney 3 | to_name: Melbourne 4 | 5 | - id: 12 6 | name: Brisbane 7 | to_name: Melbourne 8 | 9 | - id: 13 10 | name: Adelaide 11 | to_name: Melbourne 12 | -------------------------------------------------------------------------------- /Chapter04/Python/Adelaide_router_config.txt: -------------------------------------------------------------------------------- 1 | hostname Adelaide 2 | ! 3 | interface Loopback100 4 | description Adelaide router loopback 5 | ip address 100.100.100.13 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to Melbourne router G0/1 9 | ! 10 | interface GigabitEthernet1/0.113 11 | description Access to Melbourne 12 | encapsulation dot1Q 113 13 | ip address 100.0.113.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.13 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Python/Brisbane_router_config.txt: -------------------------------------------------------------------------------- 1 | hostname Brisbane 2 | ! 3 | interface Loopback100 4 | description Brisbane router loopback 5 | ip address 100.100.100.12 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to Melbourne router G0/1 9 | ! 10 | interface GigabitEthernet1/0.112 11 | description Access to Melbourne 12 | encapsulation dot1Q 112 13 | ip address 100.0.112.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.12 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Python/README.md: -------------------------------------------------------------------------------- 1 | ## Configuration render for Python 2 | 3 | ### How to run 4 | 5 | `python3 config_render.py` 6 | -------------------------------------------------------------------------------- /Chapter04/Python/Sydney_router_config.txt: -------------------------------------------------------------------------------- 1 | hostname Sydney 2 | ! 3 | interface Loopback100 4 | description Sydney router loopback 5 | ip address 100.100.100.11 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to Melbourne router G0/1 9 | ! 10 | interface GigabitEthernet1/0.111 11 | description Access to Melbourne 12 | encapsulation dot1Q 111 13 | ip address 100.0.111.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.11 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | -------------------------------------------------------------------------------- /Chapter04/Python/cisco_template_python.txt: -------------------------------------------------------------------------------- 1 | hostname {{name}} 2 | ! 3 | interface Loopback100 4 | description {{name}} router loopback 5 | ip address 100.100.100.{{id}} 255.255.255.255 6 | ! 7 | interface GigabitEthernet1/0 8 | description Connection to {{to_name}} router G0/1 9 | ! 10 | interface GigabitEthernet1/0.1{{id}} 11 | description Access to {{to_name}} 12 | encapsulation dot1Q 1{{id}} 13 | ip address 100.0.1{{id}}.2 255.255.255.252 14 | ip ospf network point-to-point 15 | ip ospf cost 100 16 | ! 17 | router ospf 100 18 | router-id 100.100.100.{{id}} 19 | network 100.0.0.0 0.255.255.255 area 0 20 | ! 21 | 22 | -------------------------------------------------------------------------------- /Chapter04/Python/config_render.py: -------------------------------------------------------------------------------- 1 | from jinja2 import Environment, FileSystemLoader 2 | import yaml 3 | 4 | env = Environment(loader=FileSystemLoader(".")) 5 | template = env.get_template("cisco_template_python.txt") 6 | 7 | with open("router_definitions.yaml") as f: 8 | routers = yaml.safe_load(f) 9 | 10 | for router in routers: 11 | router_conf = router["name"] + "_router_config.txt" 12 | with open(router_conf, "w") as f: 13 | f.write(template.render(router)) 14 | -------------------------------------------------------------------------------- /Chapter04/Python/router_definitions.yaml: -------------------------------------------------------------------------------- 1 | - id: 11 2 | name: Sydney 3 | to_name: Melbourne 4 | 5 | - id: 12 6 | name: Brisbane 7 | to_name: Melbourne 8 | 9 | - id: 13 10 | name: Adelaide 11 | to_name: Melbourne 12 | -------------------------------------------------------------------------------- /Chapter06/Device-Emulator/README.md: -------------------------------------------------------------------------------- 1 | # Router Emulator 2 | 3 | All the code examples shown in chapter 6 were tested using this router emulation. 4 | 5 | The emulator is based on QEMU and FRRouting. The instructions on how to download and run can be obtained from my github repository [brnuts/router-emulator](https://github.com/brnuts/router-emulator) 6 | -------------------------------------------------------------------------------- /Chapter06/Go/README.md: -------------------------------------------------------------------------------- 1 | ## Examples of libraries for Go 2 | 3 | ### How to run each example: 4 | 5 | `go run go-ssh-example.go` 6 | 7 | `go run go-vssh-example.go` 8 | -------------------------------------------------------------------------------- /Chapter06/Go/go-gomiko-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | gomiko "github.com/Ali-aqrabawi/gomiko/pkg" 8 | ) 9 | 10 | func main() { 11 | device := gomiko.NewDevice( 12 | "10.0.4.1", "router1", "router1", "juniper", 13 | ) 14 | if err := device.Connect(); err != nil { 15 | log.Fatal(err) 16 | } 17 | 18 | result, _ := device.SendCommand("show version") 19 | device.Disconnect() 20 | fmt.Println(result) 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Chapter06/Go/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Ali-aqrabawi/gomiko v0.0.1 h1:+SC5/pJMObRH95adNYxjZyYuqrctiBFtKeYOqxOCEJo= 2 | github.com/Ali-aqrabawi/gomiko v0.0.1/go.mod h1:yt5x1ayjDhthmzEXy7brKzvmhxL9vmCnCxPSlwVuimE= 3 | github.com/aws/aws-sdk-go v1.32.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= 4 | github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= 5 | github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 8 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 9 | github.com/gosnmp/gosnmp v1.35.0 h1:EuWWNPxTCdAUx2/NbQcSa3WdNxjzpy4Phv57b4MWpJM= 10 | github.com/gosnmp/gosnmp v1.35.0/go.mod h1:2AvKZ3n9aEl5TJEo/fFmf/FGO4Nj4cVeEc5yuk88CYc= 11 | github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= 12 | github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= 13 | github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= 14 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 15 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 16 | github.com/scrapli/scrapligo v1.1.3 h1:ifYs4mwfZs/9k2a6m2NneDOmz3etctps9IGFpbWoP2M= 17 | github.com/scrapli/scrapligo v1.1.3/go.mod h1:jvRMdb90MNnswMiku8UNXj8JZaOIPhwhcqqFwr9qeoY= 18 | github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4 h1:FHUL2HofYJuslFOQdy/JjjP36zxqIpd/dcoiwLMIs7k= 19 | github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4/go.mod h1:CJYqpTg9u5VPCoD0VEl9E68prCIiWQD8m457k098DdQ= 20 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 21 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 22 | github.com/yahoo/vssh v0.0.0-20201122023451-bfa903e660fc h1:7NDc+3ov+yAA3l6d9I65kUoqP+0372IsLTak5NHIOTE= 23 | github.com/yahoo/vssh v0.0.0-20201122023451-bfa903e660fc/go.mod h1:jlMwL65p7h2KWE8YtsG4NtzGkhLO42Q3XK8Act2ccsQ= 24 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 25 | golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 26 | golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 27 | golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 28 | golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= 29 | golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 30 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 31 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 32 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 33 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 34 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 35 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 36 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 37 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= 38 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 39 | golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI= 40 | golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 41 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= 42 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 43 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 44 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 45 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 46 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 47 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 48 | gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 49 | -------------------------------------------------------------------------------- /Chapter06/Go/gosnmp-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | snmp "github.com/gosnmp/gosnmp" 8 | ) 9 | 10 | func main() { 11 | 12 | snmp.Default.Target = "10.0.4.1" 13 | if err := snmp.Default.Connect(); err != nil { 14 | log.Fatalf("Failed Connect: %v", err) 15 | } 16 | defer snmp.Default.Conn.Close() 17 | 18 | oid := []string{"1.3.6.1.2.1.1.3.0"} //SNMPv2-MIB::sysUpTime 19 | result, err := snmp.Default.Get(oid) 20 | if err != nil { 21 | log.Fatalf("Failed Get: %v", err) 22 | } 23 | 24 | for _, variable := range result.Variables { 25 | fmt.Printf("oid: %s ", variable.Name) 26 | fmt.Printf(": %d\n", snmp.ToBigInt(variable.Value)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chapter06/Go/scrapligo-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/scrapli/scrapligo/driver/generic" 8 | "github.com/scrapli/scrapligo/driver/options" 9 | ) 10 | 11 | func main() { 12 | target, err := generic.NewDriver( 13 | "10.0.4.1", 14 | options.WithAuthNoStrictKey(), 15 | options.WithAuthUsername("netlab"), 16 | options.WithAuthPassword("netlab"), 17 | ) 18 | if err != nil { 19 | log.Fatalf("Failed to create target: %+v\n", err) 20 | } 21 | 22 | if err = target.Open(); err != nil { 23 | log.Fatalf("Failed to open: %+v\n", err) 24 | } 25 | 26 | output, err := target.Channel.SendInput("uptime") 27 | if err != nil { 28 | log.Fatalf("Failed to send command: %+v\n", err) 29 | } 30 | 31 | fmt.Println(string(output)) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Chapter06/Go/ssh-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "log" 7 | 8 | "golang.org/x/crypto/ssh" 9 | ) 10 | 11 | func main() { 12 | host := "10.0.4.1" 13 | 14 | config := &ssh.ClientConfig{ 15 | User: "netlab", 16 | HostKeyCallback: ssh.InsecureIgnoreHostKey(), 17 | Auth: []ssh.AuthMethod{ 18 | ssh.Password("netlab"), 19 | }, 20 | } 21 | conn, err := ssh.Dial("tcp", host+":22", config) 22 | if err != nil { 23 | log.Fatalf("Dial failed: %s", err) 24 | } 25 | session, err := conn.NewSession() 26 | if err != nil { 27 | log.Fatalf("NewSession failed: %s", err) 28 | } 29 | 30 | var buff bytes.Buffer 31 | session.Stdout = &buff 32 | if err := session.Run("uptime"); err != nil { 33 | log.Fatalf("Run failed: %s", err) 34 | } 35 | 36 | fmt.Println(buff.String()) 37 | } 38 | -------------------------------------------------------------------------------- /Chapter06/Go/vssh-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/yahoo/vssh" 10 | ) 11 | 12 | func main() { 13 | vs := vssh.New().Start() 14 | config := vssh.GetConfigUserPass("netlab", "netlab") 15 | vs.AddClient( 16 | "10.0.4.1:22", config, vssh.SetMaxSessions(1), 17 | ) 18 | vs.Wait() 19 | ctx, cancel := context.WithCancel(context.Background()) 20 | defer cancel() 21 | 22 | timeout, _ := time.ParseDuration("10s") 23 | rChannel := vs.Run(ctx, "uptime", timeout) 24 | 25 | for resp := range rChannel { 26 | if err := resp.Err(); err != nil { 27 | log.Println(err) 28 | continue 29 | } 30 | outTxt, _, _ := resp.GetText(vs) 31 | fmt.Println(outTxt) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter06/Python/README.md: -------------------------------------------------------------------------------- 1 | ## Examples of using libraries for Python 2 | 3 | ### How to run each example: 4 | 5 | `python3 paramiko-example.py` 6 | 7 | `python3 netmiko-example.py` 8 | 9 | `python3 async-example.py` 10 | 11 | `python3 scrapli-example.py` 12 | -------------------------------------------------------------------------------- /Chapter06/Python/async-example.py: -------------------------------------------------------------------------------- 1 | import asyncio, asyncssh, sys 2 | 3 | TARGET = { 4 | "host": "10.0.4.1", 5 | "username": "netlab", 6 | "password": "netlab", 7 | "known_hosts": None, 8 | } 9 | 10 | async def run_client() -> None: 11 | async with asyncssh.connect(**TARGET) as conn: 12 | result = await conn.run("uptime", check=True) 13 | print(result.stdout, end="") 14 | 15 | try: 16 | asyncio.get_event_loop().run_until_complete( run_client() ) 17 | except (OSError, asyncssh.Error) as execrr: 18 | sys.exit("Connection failed:" + str(execrr)) 19 | -------------------------------------------------------------------------------- /Chapter06/Python/netmiko-example.py: -------------------------------------------------------------------------------- 1 | import netmiko 2 | 3 | host = { 4 | "host": "10.0.4.1", 5 | "username": "netlab", 6 | "password": "netlab", 7 | "device_type": "linux_ssh", 8 | } 9 | 10 | with netmiko.ConnectHandler(**host) as netcon: 11 | output = netcon.send_command("uptime") 12 | 13 | print(output) 14 | -------------------------------------------------------------------------------- /Chapter06/Python/paramiko-example.py: -------------------------------------------------------------------------------- 1 | import paramiko 2 | 3 | TARGET = { 4 | "hostname": "10.0.4.1", 5 | "username": "netlab", 6 | "password": "netlab", 7 | } 8 | 9 | ssh = paramiko.SSHClient() 10 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 11 | ssh.connect(**TARGET) 12 | stdin, stdout, stderr = ssh.exec_command("uptime") 13 | stdin.close() 14 | 15 | print(stdout.read().decode("ascii")) 16 | -------------------------------------------------------------------------------- /Chapter06/Python/pysnmp-example.py: -------------------------------------------------------------------------------- 1 | from pysnmp.hlapi import * 2 | 3 | snmpIt = getCmd(SnmpEngine(), 4 | CommunityData('public'), 5 | UdpTransportTarget(('10.0.4.1', 161)), 6 | ContextData(), 7 | ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysUpTime', 0))) 8 | 9 | errEngine, errAgent, errorIndex, vars = next(snmpIt) 10 | 11 | if errEngine: 12 | print("Got engine error:", errEngine) 13 | elif errAgent: 14 | print("Got agent error:", errAgent.prettyPrint()) 15 | else: 16 | for var in vars: 17 | print(' = '.join([x.prettyPrint() for x in var])) 18 | -------------------------------------------------------------------------------- /Chapter06/Python/scrapli-example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from scrapli.driver import GenericDriver 4 | 5 | TARGET = { 6 | "host": "10.0.4.1", 7 | "auth_username": "netlab", 8 | "auth_password": "netlab", 9 | "auth_strict_key": False, 10 | } 11 | 12 | with GenericDriver(**TARGET) as conn: 13 | command_return = conn.send_command("uptime") 14 | 15 | print(command_return.result) 16 | -------------------------------------------------------------------------------- /Chapter07/Go/division-by-zero-panic-recover.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func divide(q, d int) int { 6 | fmt.Println("Dividing it now") 7 | return q / d 8 | } 9 | 10 | func main() { 11 | defer func() { 12 | if r := recover(); r != nil { 13 | fmt.Println("Got a panic:", r) 14 | } 15 | }() 16 | fmt.Println("the division is:", divide(4, 0)) 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter07/Go/division-by-zero-panic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func divide(q, d int) int { 6 | fmt.Println("Dividing it now") 7 | return q / d 8 | } 9 | 10 | func main() { 11 | fmt.Println("the division is:", divide(4, 0)) 12 | } 13 | -------------------------------------------------------------------------------- /Chapter07/Go/error-library-error-division.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func divide(q int, d int) (int, error) { 9 | if d == 0 { 10 | return 0, errors.New("divided by zero not possible") 11 | } 12 | 13 | return q / d, nil 14 | } 15 | 16 | func main() { 17 | fmt.Println(divide(10, 0)) 18 | } 19 | -------------------------------------------------------------------------------- /Chapter07/Go/error-library-fmt-division.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func divide(q int, d int) (int, error) { 8 | if d == 0 { 9 | return 0, fmt.Errorf("divided by zero not possible") 10 | } 11 | 12 | return q / d, nil 13 | } 14 | 15 | func main() { 16 | fmt.Println(divide(10, 0)) 17 | } 18 | -------------------------------------------------------------------------------- /Chapter07/Go/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.19 4 | 5 | require github.com/sirupsen/logrus v1.9.0 6 | 7 | require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect 8 | -------------------------------------------------------------------------------- /Chapter07/Go/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 6 | github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= 7 | github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 8 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 9 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 10 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 11 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= 12 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 14 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 15 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 16 | -------------------------------------------------------------------------------- /Chapter07/Go/logrus-logging.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | log "github.com/sirupsen/logrus" 5 | ) 6 | 7 | func init() { 8 | log.SetFormatter(&log.TextFormatter{ 9 | DisableColors: true, 10 | FullTimestamp: true, 11 | }) 12 | log.SetLevel(log.ErrorLevel) 13 | } 14 | 15 | func main() { 16 | 17 | log.Debug("Debug is supressed in error level") 18 | log.Info("This info won't show in error level") 19 | log.Error("Got an error here") 20 | } 21 | -------------------------------------------------------------------------------- /Chapter07/Go/move-file-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func moveFile(srcFile, dstFile string) error { 10 | src, err := os.Open(srcFile) 11 | if err != nil { 12 | return fmt.Errorf("os.Open: %v", err) 13 | } 14 | defer src.Close() 15 | 16 | dst, err := os.Create(dstFile) 17 | if err != nil { 18 | return fmt.Errorf("os.Create: %v", err) 19 | } 20 | defer dst.Close() 21 | 22 | _, err = io.Copy(dst, src) 23 | if err != nil { 24 | return fmt.Errorf("io.Copy: %v", err) 25 | 26 | } 27 | 28 | src.Close() 29 | err = os.Remove(srcFile) 30 | if err != nil { 31 | return fmt.Errorf("os.Remove: %v", err) 32 | } 33 | return nil 34 | } 35 | 36 | func main() { 37 | if err := moveFile("one.txt", "two.txt"); err != nil { 38 | fmt.Printf("Got and error: %v", err) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Chapter07/Go/one.txt: -------------------------------------------------------------------------------- 1 | DATAisNOTaREALdata 2 | -------------------------------------------------------------------------------- /Chapter07/Go/panic-example-with-defer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func squareRoot(value float64) float64 { 9 | defer fmt.Println("ending the function") 10 | if value < 0 { 11 | panic("negative values are not allowed") 12 | } 13 | 14 | return math.Sqrt(value) 15 | } 16 | 17 | func main() { 18 | fmt.Println(squareRoot(-2)) 19 | 20 | fmt.Println("done") 21 | } 22 | -------------------------------------------------------------------------------- /Chapter07/Go/panic-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func squareRoot(value float64) float64 { 9 | if value < 0 { 10 | panic("negative values are not allowed") 11 | } 12 | 13 | return math.Sqrt(value) 14 | } 15 | 16 | func main() { 17 | fmt.Println(squareRoot(-2)) 18 | 19 | fmt.Println("done") 20 | } 21 | -------------------------------------------------------------------------------- /Chapter07/Go/standard-logging-5-sev-levels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | ) 7 | 8 | var criticalLog, errorLog, warnLog, infoLog, debugLog *log.Logger 9 | 10 | func init() { 11 | file, err := os.Create("log-file.txt") 12 | if err != nil { 13 | log.Fatal(err) 14 | } 15 | flags := log.Ldate | log.Ltime 16 | criticalLog = log.New(file, "CRITICAL: ", flags) 17 | errorLog = log.New(file, "ERROR: ", flags) 18 | warnLog = log.New(file, "WARNING: ", flags) 19 | infoLog = log.New(file, "INFO: ", flags) 20 | debugLog = log.New(file, "DEBUG: ", flags) 21 | } 22 | 23 | func main() { 24 | infoLog.Print("That is a milestone") 25 | errorLog.Print("Got an error here") 26 | debugLog.Print("Extra information for a debug") 27 | warnLog.Print("You should be warned about this") 28 | } 29 | -------------------------------------------------------------------------------- /Chapter07/Go/standard-logging.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os/user" 6 | ) 7 | 8 | func main() { 9 | user, err := user.Current() 10 | if err != nil { 11 | log.Fatalf("Failed to get user with error: %v", err) 12 | } 13 | 14 | log.Printf("Current user is %s", user.Username) 15 | } 16 | -------------------------------------------------------------------------------- /Chapter07/Python/catch-else-finally-division-by-zero.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def division(q, d): 4 | return q/d 5 | 6 | try: 7 | result = division(10, 1) 8 | except ZeroDivisionError: 9 | print("Error: We should not divide by zero") 10 | else: 11 | print("Division succeded, result is:", result) 12 | finally: 13 | print("done") 14 | -------------------------------------------------------------------------------- /Chapter07/Python/catching-division-by-zero-exception.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def division(q, d): 4 | return q/d 5 | 6 | try: 7 | print(division(1, 0)) 8 | except ZeroDivisionError: 9 | print("Error: We should not divide by zero") 10 | 11 | -------------------------------------------------------------------------------- /Chapter07/Python/division-by-zero-exception.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def division(q, d): 4 | return q/d 5 | 6 | 7 | print(division(1, 0)) 8 | -------------------------------------------------------------------------------- /Chapter07/Python/logru-logging.py: -------------------------------------------------------------------------------- 1 | from loguru import logger 2 | 3 | 4 | logger.add( 5 | "log-file-{time}.txt", 6 | rotation="1 MB", 7 | colorize=False, 8 | level="ERROR", 9 | ) 10 | 11 | logger.debug("That's not going to show") 12 | logger.warning("This will not show") 13 | logger.error("Got an error") 14 | -------------------------------------------------------------------------------- /Chapter07/Python/standard-logging.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | logging.basicConfig( 4 | filename="log-file.txt", 5 | level=logging.ERROR, 6 | format="%(asctime)s.%(msecs)03d %(levelname)s: %(message)s", 7 | datefmt="%Y-%m-%d %H:%M:%S", 8 | ) 9 | logging.debug("This won't show, level is set to info") 10 | logging.info("Info is not that important as well") 11 | logging.warning("Warning will not show as well") 12 | logging.error("This is an error") -------------------------------------------------------------------------------- /Chapter08/Go/README.md: -------------------------------------------------------------------------------- 1 | # Guide to run Go examples Chapter 8 2 | 3 | ## Here are some tips to run the programs 4 | - To run one example just type: `go run .go` 5 | - Example: `go run goroutine-icmp-probe.go` 6 | - If the Go third-party package/library is not found use `go get` 7 | - Example: `go get github.com/go-ping/ping` 8 | - Some operational system will require privileges to run IMCP probe, use `sudo` if required. 9 | - Example `sudo go run .go` 10 | 11 | Enjoy -------------------------------------------------------------------------------- /Chapter08/Go/go.mod: -------------------------------------------------------------------------------- 1 | module example 2 | 3 | go 1.16 4 | 5 | require github.com/go-ping/ping v1.1.0 6 | -------------------------------------------------------------------------------- /Chapter08/Go/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= 2 | github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= 3 | github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= 4 | github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 5 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= 6 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 7 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= 8 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 9 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 10 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005 h1:pDMpM2zh2MT0kHy037cKlSby2nEhD50SYqwQk76Nm40= 11 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 12 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 13 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 14 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 15 | -------------------------------------------------------------------------------- /Chapter08/Go/goroutine-icmp-probe-wg-sync.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | 7 | "github.com/go-ping/ping" 8 | ) 9 | 10 | func myping(host string, wg *sync.WaitGroup) { 11 | defer wg.Done() 12 | p, err := ping.NewPinger(host) 13 | if err != nil { 14 | panic(err) 15 | } 16 | p.Count = 1 17 | p.SetPrivileged(true) 18 | if err = p.Run(); err != nil { 19 | panic(err) 20 | } 21 | stats := p.Statistics() // get send/receive/duplicate/rtt stats 22 | fmt.Println(host, "OK, latency is", stats.AvgRtt) 23 | } 24 | 25 | func main() { 26 | var targets = []string{"yahoo.com", "google.com", "cisco.com", "cern.ch"} 27 | 28 | var wg sync.WaitGroup 29 | wg.Add(len(targets)) 30 | for _, target := range targets { 31 | go myping(target, &wg) 32 | } 33 | wg.Wait() 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Chapter08/Go/goroutine-icmp-probe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/go-ping/ping" 8 | ) 9 | 10 | func myPing(host string) { 11 | p, err := ping.NewPinger(host) 12 | if err != nil { 13 | panic(err) 14 | } 15 | p.Count = 1 16 | p.SetPrivileged(true) 17 | if err = p.Run(); err != nil { 18 | panic(err) 19 | } 20 | stats := p.Statistics() // get send/receive/duplicate/rtt stats 21 | fmt.Println(host, "OK, latency is", stats.AvgRtt) 22 | } 23 | 24 | func main() { 25 | targets := []string{"yahoo.com", "google.com", "cisco.com", "cern.ch"} 26 | 27 | for _, target := range targets { 28 | go myPing(target) 29 | } 30 | time.Sleep(time.Second * 3) //Wait 3 seconds 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Chapter08/Go/parallelism.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "sync" 7 | "math" 8 | ) 9 | 10 | var wg sync.WaitGroup 11 | 12 | func count() { 13 | defer wg.Done() 14 | for i := 1; i < 5; i++ { 15 | fmt.Println(i) 16 | var z float64 = 0 17 | for ; z < 1e8; z++ { 18 | _ = math.Sqrt(z) 19 | } 20 | } 21 | } 22 | 23 | func main() { 24 | fmt.Println("Version", runtime.Version()) 25 | fmt.Println("NumCPU", runtime.NumCPU()) 26 | fmt.Println("GOMAXPROCS", runtime.GOMAXPROCS(0)) 27 | wg.Add(4) 28 | go count() 29 | go count() 30 | go count() 31 | go count() 32 | wg.Wait() 33 | } 34 | -------------------------------------------------------------------------------- /Chapter08/Python/README.md: -------------------------------------------------------------------------------- 1 | # Guide to run the examples 2 | 3 | ## Running the examples 4 | - To run on example just type: `python "name of the program".py` 5 | - Example: `python asyncio-example.py` 6 | - Some Python installation might require you to use `python3` instead. 7 | - Example: `python3 asyncio-example.py` 8 | 9 | - `ICMP` probes sometimes requires privilege access, if so use `sudo` in front. 10 | - Example: `sudo python asyncio-example.py` 11 | 12 | - Missing third-party modules/libraries can be added using `pip` 13 | - Example: `pip install pythonping` 14 | - Some might need to run: `pip3 install pythonping` if pip not available 15 | 16 | Enjoy -------------------------------------------------------------------------------- /Chapter08/Python/asyncio-example-fixed.py: -------------------------------------------------------------------------------- 1 | from aioping import ping 2 | import asyncio 3 | 4 | TARGETS = ["yahoo.com", "google.com", "cisco.com", "cern.ch"] 5 | 6 | 7 | async def myping(host): 8 | try: 9 | delay = await ping(host) 10 | print("%s OK, latency is %.3f ms" % (host, delay * 1000)) 11 | except TimeoutError: 12 | print(host, "FAILED") 13 | 14 | 15 | async def main(): 16 | coroutines = [] 17 | for target in TARGETS: 18 | coroutines.append(asyncio.ensure_future(myping(target))) 19 | for coroutine in coroutines: 20 | await coroutine 21 | 22 | 23 | if __name__ == "__main__": 24 | asyncio.run(main()) 25 | -------------------------------------------------------------------------------- /Chapter08/Python/asyncio-example.py: -------------------------------------------------------------------------------- 1 | from pythonping import ping 2 | import asyncio 3 | 4 | TARGETS = ["yahoo.com", "google.com", "cisco.com", "cern.ch"] 5 | 6 | 7 | async def myping(host): 8 | response = ping(host) 9 | if response.success: 10 | print("%s OK, latency is %.2fms" % (host, response.rtt_avg_ms)) 11 | else: 12 | print(host, "FAILED") 13 | 14 | 15 | async def main(): 16 | coroutines = [] 17 | for target in TARGETS: 18 | coroutines.append(asyncio.ensure_future(myping(target))) 19 | for coroutine in coroutines: 20 | await coroutine 21 | 22 | 23 | if __name__ == "__main__": 24 | asyncio.run(main()) 25 | -------------------------------------------------------------------------------- /Chapter08/Python/multiple-pyping-example.py: -------------------------------------------------------------------------------- 1 | from pythonping import ping 2 | from multiprocessing import Process 3 | 4 | TARGETS = ["yahoo.com", "google.com", "cisco.com", "cern.ch"] 5 | 6 | def myping(host): 7 | response = ping(host) 8 | if response.success: 9 | print("%s OK, latency is %.2fms" % (host, response.rtt_avg_ms)) 10 | else: 11 | print(host, "FAILED") 12 | 13 | def main(): 14 | for host in TARGETS: 15 | Process(target=myping, args=(host,)).start() 16 | 17 | if __name__ == "__main__": 18 | main() 19 | -------------------------------------------------------------------------------- /Chapter08/Python/performance-asyncio-threads-process.py: -------------------------------------------------------------------------------- 1 | from pythonping import ping 2 | from multiprocessing import Process 3 | import time 4 | import threading 5 | import sys 6 | import asyncio 7 | 8 | 9 | def myping(host): 10 | response = ping(host) 11 | 12 | 13 | class myPing(threading.Thread): 14 | def __init__(self, host): 15 | threading.Thread.__init__(self) 16 | self.host = host 17 | 18 | def run(self): 19 | response = ping(self.host) 20 | 21 | 22 | def main(total): 23 | print("Multi-threading test ", end="") 24 | start = time.time() 25 | threads = [] 26 | for i in range(total): 27 | t = myPing("127.0.0.1") 28 | threads.append(t) 29 | t.start() 30 | for t in threads: 31 | t.join() 32 | print("--- duration %.3f seconds" % (time.time() - start)) 33 | 34 | print("Multi-processing test", end="") 35 | start = time.time() 36 | processes = [] 37 | for i in range(total): 38 | p = Process(target=myping, args=("127.0.0.1",)) 39 | processes.append(p) 40 | p.start() 41 | for p in processes: 42 | p.join() 43 | print("--- duration %.3f seconds" % (time.time() - start)) 44 | 45 | 46 | async def myping_async(host): 47 | response = ping(host) 48 | 49 | 50 | async def main_async(total): 51 | print("Asyncio test", end="") 52 | start = time.time() 53 | coroutines = [] 54 | for i in range(total): 55 | coroutines.append(asyncio.ensure_future(myping_async("127.0.0.1"))) 56 | for coroutine in coroutines: 57 | await coroutine 58 | print("--- duration %.3f seconds" % (time.time() - start)) 59 | 60 | 61 | if __name__ == "__main__": 62 | if len(sys.argv) != 2 or (int(sys.argv[1]) > 100 or int(sys.argv[1]) < 1): 63 | print("Need one argument number between 1 and 100") 64 | sys.exit(1) 65 | total = int(sys.argv[1]) 66 | main(total) 67 | asyncio.run(main_async(total)) 68 | -------------------------------------------------------------------------------- /Chapter08/Python/performance-thread-process-example.py: -------------------------------------------------------------------------------- 1 | from pythonping import ping 2 | from multiprocessing import Process 3 | import time 4 | import threading 5 | import sys 6 | 7 | 8 | def myping(host): 9 | response = ping(host) 10 | 11 | 12 | class myPing(threading.Thread): 13 | def __init__(self, host): 14 | threading.Thread.__init__(self) 15 | self.host = host 16 | 17 | def run(self): 18 | response = ping(self.host) 19 | 20 | 21 | def main(): 22 | if len(sys.argv) != 2 or (int(sys.argv[1]) > 100 or int(sys.argv[1]) < 1): 23 | print("Need one argument number between 1 and 100") 24 | sys.exit(1) 25 | 26 | total = int(sys.argv[1]) 27 | 28 | print("Multi-threading test ", end="") 29 | start = time.time() 30 | threads = [] 31 | for i in range(total): 32 | t = myPing("127.0.0.1") 33 | threads.append(t) 34 | t.start() 35 | for t in threads: 36 | t.join() 37 | print("--- duration %.3f seconds" % (time.time() - start)) 38 | 39 | print("Multi-processing test", end="") 40 | start = time.time() 41 | processes = [] 42 | for i in range(total): 43 | p = Process(target=myping, args=("127.0.0.1",)) 44 | processes.append(p) 45 | p.start() 46 | for p in processes: 47 | p.join() 48 | print("--- duration %.3f seconds" % (time.time() - start)) 49 | 50 | 51 | if __name__ == "__main__": 52 | main() 53 | -------------------------------------------------------------------------------- /Chapter08/Python/single-ping-example.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | TARGET = "yahoo.com" 4 | 5 | command = ["ping", "-c", "1", TARGET] 6 | response = subprocess.call(command, stdout=subprocess.DEVNULL) 7 | 8 | if response == 0: 9 | print(TARGET, "OK") 10 | else: 11 | print(TARGET, "FAILED") 12 | -------------------------------------------------------------------------------- /Chapter08/Python/single-pyping-example.py: -------------------------------------------------------------------------------- 1 | from pythonping import ping 2 | 3 | TARGET = "yahoo.com" 4 | 5 | response = ping(TARGET, count=1) 6 | if response.success: 7 | print(TARGET, "OK") 8 | else: 9 | print(TARGET, "FAILED") -------------------------------------------------------------------------------- /Chapter08/Python/threads-pyping-example.py: -------------------------------------------------------------------------------- 1 | from pythonping import ping 2 | import threading 3 | 4 | TARGETS = ["yahoo.com", "google.com", "cisco.com", "cern.ch"] 5 | 6 | class myPing(threading.Thread): 7 | def __init__(self, host): 8 | threading.Thread.__init__(self) 9 | self.host = host 10 | 11 | def run(self): 12 | response = ping(self.host) 13 | if response.success: 14 | print("%s OK, latency is %.2fms" % (self.host, response.rtt_avg_ms)) 15 | else: 16 | print(self.host, "FAILED") 17 | 18 | def main(): 19 | for host in TARGETS: 20 | myPing(host).start() 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /Chapter08/probe-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.19-alpine 2 | WORKDIR /usr/src/app 3 | COPY go.mod go.sum ./ 4 | RUN go mod download && go mod verify 5 | 6 | COPY icmp-probe-service.go ./ 7 | RUN go build -v -o /usr/local/bin/probe-service 8 | 9 | CMD ["/usr/local/bin/probe-service"] 10 | -------------------------------------------------------------------------------- /Chapter08/probe-service/README.md: -------------------------------------------------------------------------------- 1 | # To build 2 | `docker build . –t probe-service` 3 | 4 | # To run single service 5 | `docker run -d -p 9900:9900 probe-service` 6 | 7 | # To run multiple services 8 | `docker compose up -d` 9 | 10 | # To run docker swarm in a leader host 11 | `docker swarm init` 12 | 13 | # To add docker swarm nodes 14 | `docker swarm join --token :` 15 | -------------------------------------------------------------------------------- /Chapter08/probe-service/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "1.0" 2 | services: 3 | probe1: 4 | image: "probe-service:latest" 5 | ports: ["9001:9900"] 6 | probe2: 7 | image: "probe-service:latest" 8 | ports: ["9002:9900"] 9 | probe3: 10 | image: "probe-service:latest" 11 | ports: ["9003:9900"] 12 | probe4: 13 | image: "probe-service:latest" 14 | ports: ["9004:9900"] 15 | probe5: 16 | image: "probe-service:latest" 17 | ports: ["9005:9900"] -------------------------------------------------------------------------------- /Chapter08/probe-service/go.mod: -------------------------------------------------------------------------------- 1 | module example 2 | 3 | go 1.16 4 | 5 | require github.com/go-ping/ping v1.1.0 6 | -------------------------------------------------------------------------------- /Chapter08/probe-service/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= 2 | github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= 3 | github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= 4 | github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 5 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= 6 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 7 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= 8 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 9 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 10 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005 h1:pDMpM2zh2MT0kHy037cKlSby2nEhD50SYqwQk76Nm40= 11 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 12 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 13 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 14 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 15 | -------------------------------------------------------------------------------- /Chapter08/probe-service/icmp-probe-service.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "os" 8 | "strings" 9 | "sync" 10 | "time" 11 | 12 | "github.com/go-ping/ping" 13 | ) 14 | 15 | func probe(host string, w http.ResponseWriter, wg *sync.WaitGroup) { 16 | defer wg.Done() 17 | p, err := ping.NewPinger(host) 18 | if err != nil { 19 | fmt.Fprintf(w, "error ping creation: %v\n", err) 20 | return 21 | } 22 | p.Count = 1 23 | p.Timeout = time.Second * 2 24 | p.SetPrivileged(true) 25 | if err = p.Run(); err != nil { 26 | fmt.Fprintf(w, "error ping sent: %v\n", err) 27 | return 28 | } 29 | stats := p.Statistics() 30 | if stats.PacketLoss == 0 { 31 | fmt.Fprintf(w, "%s latency is %s\n", host, stats.AvgRtt) 32 | } else { 33 | fmt.Fprintf(w, "%s no response timeout\n", host) 34 | } 35 | } 36 | 37 | func probeTargets(w http.ResponseWriter, r *http.Request) { 38 | httpTargets := r.URL.Query().Get("targets") 39 | targets := strings.Split(httpTargets, ",") 40 | if len(httpTargets) == 0 || len(targets) > 1000 { 41 | fmt.Fprintf(w, "error: 0 < targets < 1000\n") 42 | return 43 | } 44 | 45 | var wg sync.WaitGroup 46 | wg.Add(len(targets)) 47 | for _, target := range targets { 48 | log.Println("requested ICMP probe for", target) 49 | go probe(target, w, &wg) 50 | } 51 | wg.Wait() 52 | } 53 | 54 | func main() { 55 | var listen string 56 | if port, ok := os.LookupEnv("PORT"); ok { 57 | listen = ":" + port 58 | } else { 59 | listen = ":9900" 60 | } 61 | 62 | http.HandleFunc("/latency", probeTargets) 63 | log.Fatal(http.ListenAndServe(listen, nil)) 64 | } 65 | -------------------------------------------------------------------------------- /Chapter09/NetworkX/.ipynb_checkpoints/example-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "facdcc43", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import yaml\n", 11 | "\n", 12 | "with open('config.yml', 'r') as file:\n", 13 | " inputf = yaml.safe_load(file)\n", 14 | " print(inputf)\n" 15 | ] 16 | } 17 | ], 18 | "metadata": { 19 | "kernelspec": { 20 | "display_name": "Python 3 (ipykernel)", 21 | "language": "python", 22 | "name": "python3" 23 | }, 24 | "language_info": { 25 | "codemirror_mode": { 26 | "name": "ipython", 27 | "version": 3 28 | }, 29 | "file_extension": ".py", 30 | "mimetype": "text/x-python", 31 | "name": "python", 32 | "nbconvert_exporter": "python", 33 | "pygments_lexer": "ipython3", 34 | "version": "3.10.9" 35 | } 36 | }, 37 | "nbformat": 4, 38 | "nbformat_minor": 5 39 | } 40 | -------------------------------------------------------------------------------- /Chapter09/NetworkX/example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 55, 6 | "id": "84f4be71", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import networkx as nx\n", 11 | "import yaml\n", 12 | "\n", 13 | "G = nx.Graph()\n", 14 | "devices = {}\n", 15 | "\n", 16 | "def build_all():\n", 17 | " with open('topology.yaml', 'r') as file:\n", 18 | " yfile = yaml.safe_load(file)\n", 19 | "\n", 20 | " for i, x in enumerate(yfile['devices']):\n", 21 | " devices[x]=i\n", 22 | " G.add_node(i, name=x)\n", 23 | " for link in yfile['links']:\n", 24 | " G.add_edge(devices[link[0]], devices[link[1]])\n" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 56, 30 | "id": "dfab6564", 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "build_all()" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 57, 40 | "id": "90c36f71", 41 | "metadata": {}, 42 | "outputs": [ 43 | { 44 | "name": "stdout", 45 | "output_type": "stream", 46 | "text": [ 47 | "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\n" 48 | ] 49 | } 50 | ], 51 | "source": [ 52 | "print(G.nodes)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 58, 58 | "id": "e42f041a", 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "[(0, 1), (1, 2), (2, 3), (2, 4), (2, 5), (3, 6), (3, 7), (4, 6), (4, 7), (5, 6), (5, 7), (6, 8), (6, 9), (6, 10), (7, 8), (7, 9), (7, 10), (8, 11), (9, 11), (10, 11), (11, 12)]\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "print(G.edges)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 59, 76 | "id": "846b915f", 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/plain": [ 82 | "1" 83 | ] 84 | }, 85 | "execution_count": 59, 86 | "metadata": {}, 87 | "output_type": "execute_result" 88 | } 89 | ], 90 | "source": [ 91 | "nx.node_connectivity(G, devices[\"pc-a\"], devices[\"internet\"])" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 60, 97 | "id": "cca45df6", 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "G.remove_edge(1,2)" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 61, 107 | "id": "10057e2a", 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "0" 114 | ] 115 | }, 116 | "execution_count": 61, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "nx.node_connectivity(G, devices[\"pc-a\"], devices[\"internet\"])" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 62, 128 | "id": "4a96532c", 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [ 132 | "G.add_edge(1,2)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 63, 138 | "id": "0b6c71ee", 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "data": { 143 | "text/plain": [ 144 | "1" 145 | ] 146 | }, 147 | "execution_count": 63, 148 | "metadata": {}, 149 | "output_type": "execute_result" 150 | } 151 | ], 152 | "source": [ 153 | "nx.node_connectivity(G, devices[\"pc-a\"], devices[\"internet\"])" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 64, 159 | "id": "7d3c6956", 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "G.remove_node(devices[\"core-a2\"])" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 65, 169 | "id": "8cf0d08f", 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "data": { 174 | "text/plain": [ 175 | "1" 176 | ] 177 | }, 178 | "execution_count": 65, 179 | "metadata": {}, 180 | "output_type": "execute_result" 181 | } 182 | ], 183 | "source": [ 184 | "nx.node_connectivity(G, devices[\"pc-a\"], devices[\"internet\"])" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 66, 190 | "id": "6d717310", 191 | "metadata": {}, 192 | "outputs": [], 193 | "source": [ 194 | "G.remove_node(devices[\"core-a1\"])" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 67, 200 | "id": "8afb549e", 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "data": { 205 | "text/plain": [ 206 | "1" 207 | ] 208 | }, 209 | "execution_count": 67, 210 | "metadata": {}, 211 | "output_type": "execute_result" 212 | } 213 | ], 214 | "source": [ 215 | "nx.node_connectivity(G, devices[\"pc-a\"], devices[\"internet\"])" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": 68, 221 | "id": "d62b462f", 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "G.remove_node(devices[\"core-a3\"])" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 69, 231 | "id": "66825927", 232 | "metadata": {}, 233 | "outputs": [ 234 | { 235 | "data": { 236 | "text/plain": [ 237 | "0" 238 | ] 239 | }, 240 | "execution_count": 69, 241 | "metadata": {}, 242 | "output_type": "execute_result" 243 | } 244 | ], 245 | "source": [ 246 | "nx.node_connectivity(G, devices[\"pc-a\"], devices[\"internet\"])" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "id": "e66ff455", 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [] 256 | } 257 | ], 258 | "metadata": { 259 | "kernelspec": { 260 | "display_name": "Python 3 (ipykernel)", 261 | "language": "python", 262 | "name": "python3" 263 | }, 264 | "language_info": { 265 | "codemirror_mode": { 266 | "name": "ipython", 267 | "version": 3 268 | }, 269 | "file_extension": ".py", 270 | "mimetype": "text/x-python", 271 | "name": "python", 272 | "nbconvert_exporter": "python", 273 | "pygments_lexer": "ipython3", 274 | "version": "3.10.9" 275 | } 276 | }, 277 | "nbformat": 4, 278 | "nbformat_minor": 5 279 | } 280 | -------------------------------------------------------------------------------- /Chapter09/NetworkX/load_topology.py: -------------------------------------------------------------------------------- 1 | import networkx as nx 2 | import yaml 3 | 4 | G = nx.Graph() 5 | devices = {} 6 | 7 | with open("topology.yaml", "r") as file: 8 | yfile = yaml.safe_load(file) 9 | 10 | for i, x in enumerate(yfile["devices"]): 11 | devices[x] = i 12 | G.add_node(i, name=x) 13 | for link in yfile["links"]: 14 | G.add_edge(devices[link[0]], devices[link[1]]) 15 | -------------------------------------------------------------------------------- /Chapter09/NetworkX/topology.yaml: -------------------------------------------------------------------------------- 1 | devices: 2 | - pc-a 3 | - cpe-a 4 | - acc-a 5 | - core-a1 6 | - core-a2 7 | - core-a3 8 | - core-s1 9 | - core-s2 10 | - core-i1 11 | - core-i2 12 | - core-i3 13 | - border 14 | - internet 15 | 16 | links: 17 | - - pc-a 18 | - cpe-a 19 | - - cpe-a 20 | - acc-a 21 | - - acc-a 22 | - core-a1 23 | - - acc-a 24 | - core-a2 25 | - - acc-a 26 | - core-a3 27 | - - core-a1 28 | - core-s1 29 | - - core-a1 30 | - core-s2 31 | - - core-a2 32 | - core-s1 33 | - - core-a2 34 | - core-s2 35 | - - core-a3 36 | - core-s1 37 | - - core-a3 38 | - core-s2 39 | - - core-s1 40 | - core-i1 41 | - - core-s1 42 | - core-i2 43 | - - core-s1 44 | - core-i3 45 | - - core-s2 46 | - core-i1 47 | - - core-s2 48 | - core-i2 49 | - - core-s2 50 | - core-i3 51 | - - core-i1 52 | - border 53 | - - core-i2 54 | - border 55 | - - core-i3 56 | - border 57 | - - border 58 | - internet 59 | -------------------------------------------------------------------------------- /Chapter10/NetworkLab/AUTOMATION.md: -------------------------------------------------------------------------------- 1 | # Automation for devices in the lab 2 | 3 | [netlab](https://github.com/brnuts/netlab/tree/main/Go) is a Go program that creates software wires between devices using veth. 4 | 5 | [show-connections.py](https://github.com/brnuts/netlab/blob/main/Python/show-connections.py) which is a program in Python for checking connections 6 | 7 | [configure-ip-wan.py](https://github.com/brnuts/netlab/blob/main/Python/configure-ip-wan.py) which is a program in Python for allocation IPs 8 | 9 | [run-command.py](https://github.com/brnuts/netlab/blob/main/Python/run-command.py) is a program that run a command in a device that requires a bastion to connect. 10 | -------------------------------------------------------------------------------- /Chapter10/NetworkLab/README.md: -------------------------------------------------------------------------------- 1 | # Network Lab 2 | 3 | To launch a pre-build Linux host with the routers already running for network lab, just use the pre-build image below. 4 | 5 | ## Using pre-build image on VirtualBox 6 | - Download image at 7 | ``` 8 | https://www.dropbox.com/s/2l788jzbpe02rnt/netlab.vdi.bz3?dl=0 9 | ``` 10 | * Uncompress `netlab.vdi.bz3` 11 | * Create new VM on VirtualBox using the pre-built image as the hard disk `netlab.vdi` 12 | * Add port forwarding to 22 to access SSH by going to Virtualbox settings for the VM and configure NAT network with port forwarding 22, so you can access the network emulation via SSH. With that you can access the network lab by doing `ssh netlab@localhost` 13 | 14 | 15 | 16 | * All devices including the host have the username `netlab` with password `netlab`. 17 | * `sudo` is configured to be used by username `netlab` without password. 18 | * Access to `vtysh` on the routers via username `vtysh` with password `vtysh`. 19 | 20 | * (Optional) Install Guest Additions on the Linux VM, use these steps: 21 | * Open VirtualBox. 22 | * Right-click the virtual machine, select the Start submenu and choose the Normal Start option. 23 | * Sign in to netlab (username: `netlab` password: `netlab`) 24 | * Click the Devices menu and select the Insert Guest Additions CD image option. 25 | * On Linux do `sudo mount /dev/cdrom` 26 | * Run the command `sudo sh /dev/cdrom0/VBoxLinuxAdditions.run` 27 | * Reboot your VM 28 | 29 | ## Using Qemu or building yourself the image 30 | If you want to do yourself or use Qemu image instead, please visit my github instructions at: 31 | https://github.com/brnuts/netlab 32 | 33 | # Connecting the devices 34 | To connect the devices you will just need to get the Go package that connect them for you located at https://github.com/brnuts/netlab/Go 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Network Programming and Automation Essentials 2 | 3 | 4 | 5 | This is the code repository for [Network Programming and Automation Essentials](https://www.packtpub.com/product/network-programming-and-automation-essentials/9781803233666?utm_source=github&utm_medium=repository&utm_campaign=9781786461629), published by Packt. 6 | 7 | **Get started in the realm of network automation using Python and Go** 8 | 9 | ## What is this book about? 10 | This book is for network architects, network engineers, and software professionals looking to integrate programming into networks. Network engineers following traditional techniques can use this book to transition into modern-day network automation and programming. Familiarity with networking concepts is a prerequisite. 11 | 12 | This book covers the following exciting features: 13 | * Understand the foundation of network programming 14 | * Explore software-defined networks and related families 15 | * Recognize the differences between Go and Python through comparison 16 | * Leverage the best practices of Go and Python 17 | * Create your own network automation testing framework using network emulation 18 | * Acquire skills in using automation frameworks and strategies for automation 19 | 20 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1803233664) today! 21 | 22 | https://www.packtpub.com/ 24 | 25 | ## Instructions and Navigations 26 | All of the code is organized into folders. For example, Chapter04. 27 | 28 | The code will look like the following: 29 | ``` 30 | from paramiko import SSHClient 31 | 32 | client = SSHClient() 33 | client.connect('10.1.1.1', username='user', password='pw') 34 | ``` 35 | 36 | **Following is what you need for this book:** 37 | This book is for network architects, network engineers, and software professionals looking to integrate programming into networks. Network engineers following traditional techniques can use this book to transition into modern-day network automation and programming. Familiarity with networking concepts is a prerequisite. 38 | 39 | With the following software and hardware list you can run all code files present in the book (Chapter 4-10). 40 | ### Software and Hardware List 41 | | Chapter | Software required | OS required | 42 | | -------- | ------------------------------------ | ----------------------------------- | 43 | | 1-10 | Preferably Go language version 1.20 or later | Windows, Mac OS X, and Linux (Any) | 44 | | 1-10 | referably Python version 3.10.9 or later | Windows, Mac OS X, and Linux (Any) | 45 | 46 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://packt.link/AXHbe). 47 | 48 | ### Related products 49 | * Network Automation with Go [[Packt]](https://www.packtpub.com/product/network-automation-with-go/9781800560925?utm_source=github&utm_medium=repository&utm_campaign=9781800560925) [[Amazon]](https://www.amazon.com/dp/1800560923) 50 | 51 | * Mastering Python Networking - Fourth Edition [[Packt]](https://www.packtpub.com/product/mastering-python-networking-fourth-edition/9781803234618?utm_source=github&utm_medium=repository&utm_campaign=9781803234618) [[Amazon]](https://www.amazon.com/dp/180323461X) 52 | 53 | ## Get to Know the Author 54 | **Claus Töpke** 55 | is a product developer and founder of Telcomanager. He has worked with large network service providers, such as Telstra, NBN Australia, NZ Telecom, AWS Australia, AWS US, and Embratel. He has also worked in conjunction with large network technology corporations, such as Nokia, Amazon, Juniper, and Cisco. He has been able to experience different job titles, passing through fields such as network engineering, network performance, product development, and software engineering. His experience with network automation has led to the construction of several products and systems for different companies. He also worked on network performance for his master’s thesis and wrote a book about service providers. 56 | 57 | 58 | ### Download a free PDF 59 | 60 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
61 |

https://packt.link/free-ebook/9781803233666

--------------------------------------------------------------------------------