Life, Love, Sex, Negative Beliefs, startup regrets, nanog90, Groq LPU, LLM from scratch, ssh3, eBFP BGP, RPKI, TIANHE-3

I hit rock bottom this week. I hope I finally closed one door in my life so I give myself the chance to open others. Made the wrong decision? It is easy when you look back. Do I regret it? The most annoying thing is these are failures so you can’t go back and recover. But I was so bloody newbie!!!…. At least after 5 years…

“For every reason it’s not possible, there are hundreds of people who have faced the same circumstances and succeeded.” Jack Canfield

Head down, crying, cursing, whatever, but forwards. As it has always been.

—-

Somehow managed to list to long videos, something I normally can’t manage (because lack of time, etc)

Negative Beliefs, avoid bitterness, aim for greatness (remarkable things), scape the darkness: Jordan B Peterson with Modern Wisdom: video, podcast.

Find and keep Love: video. 1st Get your shit together. Communication is critical. Be careful with your shopping list….

Good Sex: video. Communicate….

Orgasm: video. Haven’t seen it completely yet but very interesting. Use your tongue wisely.

— Other things:

Startup decisions and regrets: page. Interesting. I think most of things are very specific but still good to read.

Nanog90: agenda I didnt want the videos but I reviewed several pdfs and these ones look interesting:

Abstract Ponderings: A ten-year retrospective. Rob Shakir – Google: video

https://rob.sh/post/reimagining-network-devices/
https://rob.sh/post/coaching/
https://cdn.rob.sh/files/the-next-spring-forward_2018.pdf
https://research.google/research-areas/networking/

AI Data Center networks – Juniper – video

Using gNOI capabilities to simplify software upgrade use case: video – I had to idea about gNOI so looks interesting. It is crazy that still in XXI, automating a network device is so painful. Thanks to all vendors to make your life miserable.

Go lang for network engineers: video – I always thought that Golang had a massive potential for network automation but there was always lack of support and python is the king. So nice to see that Arista has things to offer.

PTP in Meta: video and blog.

There are more things, but havent had the chance to review them.

—-

It looks there is new chatbot that is not using the standard NVIDIA GPU. Groq uses LPU (Language Processing Unit). And they say it is better than a GPU. They have this paper but I can’t really see feature of that LPU.

Slurp’it: Show this blog, and the product looks interesting but although is free, it is not opensource and at the end of they you dont want a new vendor-lockin

Container lab in kubernetes: Clabernetes. I would like to play with this one day.

NetDev0x17: videos and sessions. link This is quite low details and most of the time beyond my knowledge. Again, something to take a look at some point.

LLM from scratch: repo. Looks very interesting. But the book it is going to take a long time to hit the market.

ssh3: repo. Interesting experiment.

eBFP and BGP: blog. Really interesting. Another thing that always wanted to play with.

Orange RPKI: old news but still interesting to see how much damaged can cause RPKI in the wrong hands…

China TIANHE-3 Supercomputer: Very interesting. Link.

GPT-Pilot

I guess there are hundreds of project that try to use GPT to build apps. I found this one and looks very nice. I would like to use it if I find time for one idea.

Curl, Yaml, scalars, Elixir, git stash

I haven’t watched this video, but looks like the holly book of curl!!!

I'd recommend starting at ~34 minutes.

·You can specify multiple URLS with multiple output options in a single command. Doing this or using globbing (see below) to the same host will use persistent connections and greatly improve performance because the same L5 session is used

·trurl is also made by the project and allows you to programmatically manipulate URLs (change server, path, query parameters, etc.). Pretty neat: https://github.com/curl/trurl

·curl supports URL globbing: curl https://{ftp,www,test}.example.com/img[1-22].jpg -o "foo_#2_#1.jpg"

·By default, curl will resolve requests serially when multiple URLS or globbing is specified, but curl is capable of doing parallel transfers with the -Z or --parallel option. And can do anywhere from 2-300 transfers in parallel. This also has the potential to parallel-ize HTTP/3 transfers even from single URLs.

·You can do curl --help category to get a list of help categories for narrowing down options by categories like http or output

· Long commands for curl can be specified in a file and given to curl either via stdin or -K / --config - These files are essentially just command lines in a file

·You can use the --trace option to provide tcpdump type output from curl. Saving the need to to start tcpdump in the background if you just want to see what's happening from curl

·You can use --connect-to to specify a different DNS name to go to (instead of the one specified in the URL) which is similar to the --resolve option, but doesn't require the user to lookup the IP address ahead of time

·You can override the DNS server that you use to resolve URLs via --dns-ipv4-addr 8.8.8.8 for example

·You can add --libcurl to any curl command and it will spit out C source-code that implements the same command line in C via the library libcurl

·You can set the environment variable SSLKEYLOGFILE to a file name and it will save the runtime TLS secrets to that file, and use that file in WireShark along with a dump of the traffic from tcpdump to see the contents of encrypted HTTP streams

·You can choose to only download files that have changed since the last time they were downloaded with curl via --etag-save <etag_file> and --etag-compare <etag_file>

·You can skip adding the extra -H "Content-Type: application/json" when getting or posting JSON data (with -d), by specifying --json instead of just -d

·You can create JSON easily from the command line with the tool jo: https://github.com/jpmens/jo (basically a reverse jq)

Rant about yaml. And something I learned about yaml some months ago and forgot about it: scalars for making multiline work in yaml.

Elixir: a programming language based on Erlang. Really impressive reports! But still I would like to learn golang (if I ever learn properly python 🙂

git stash: I didnt know about this git command until last week, very handy.

Python: cycle and setattr

This week a colleague refactor a script that I wrote and the end was pretty different from what I did. The logic was the same but the code was very differnt. I learnt two things about python

setattr: This method provides an alternate means to assign values to class variables, in addition to constructors and object functions. It comes in handy when we want to add a new attribute to an object and assigning it a value
cycle: . This function takes an iterable inputs as an argument and returns an infinite iterator over the values in inputs that returns to the beginning once the end of inputs is reached. 

API scripts: CML and Vsphere

In the last months I have been trying to practice the knowledge from CCNA DevNet and managed to wrote very basic scripts using API.


CML is a simulation solution from Cisco that actually works (you have to pay and need hardware). There are nice docs out there:

CML sandbox

CML Starting guide + API examples (this saved me)

CML simulation lifecycle example (havent tried yet)

CML: I actually struggled in this one regarding how to authenticate….. Checking some pages I worked out. I was trying to use the theory from DevNet but no joy. The idea is to restore a lab after you have made many changes. The script log into CML, delete the lab and restore with a provided backup.


Some docs for vsphere api:

Vsphere create session: (quite useful)

vcenter REST API authentication

vcenter API with Postman

Vsphere postman examples (need to take a look)

Vsphere: This is even simpler…. at least in this one I didnt struggle with the auth as the documentation was quite clear. But the original goal of restore a VM from a snapshot looks like is not available via API.

CCNA DevNet Notes

1) Python Requests status code checks:

r.status_code == requests.codes.ok

2) Docker publish ports:

$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

This binds port 8080 of the container to TCP port 80 on 127.0.0.1 of the host machine. You can also specify udp and sctp ports. The Docker User Guide explains in detail how to manipulate ports in Docker.

3) HTTP status codes:

1xx informational
2xx Successful
 201 created
 204 no content (post received by server)
3xx Redirect
 301 moved permanently - future requests should be directed to the given URI
 302 found - requested resource resides temporally under a different URI
 304 not modified
4xx Client Error
 400 bad request
 401 unauthorized (user not authenticated or failed)
 403 forbidden (need permissions)
 404 not found
5xx Server Error
 500 internal server err - generic error message
 501 not implemented
 503 service unavailable

4) Python dictionary filters:

my_dict = {8:'u',4:'t',9:'z',10:'j',5:'k',3:'s'}

# filter(function,iterables)
new_dict = dict(filter(lambda val: val[0] % 3 == 0, my_dict.items()))

print("Filter dictionary:",new_filt)

5) HTTP Authentication

Basic: For "Basic" authentication the credentials are constructed by first combining the username and the password with a colon (aladdin:opensesame), and then by encoding the resulting string in base64 (YWxhZGRpbjpvcGVuc2VzYW1l).

Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

---
auth_type = 'Basic'
creds = '{}:{}'.format(user,pass)
creds_b64 = base64.b64encode(creds)
header = {'Authorization': '{}{}'.format(auth_type,creds_b64)}

Bearer:

Authorization: Bearer <TOKEN>

6) “diff -u file1.txt file2.txt”. link1 link2

The unified format is an option you can add to display output without any redundant context lines

$ diff -u file1.txt file2.txt                                                                                                            
--- file1.txt   2018-01-11 10:39:38.237464052 +0000                                                                                              
+++ file2.txt   2018-01-11 10:40:00.323423021 +0000                                                                                              
@@ -1,4 +1,4 @@                                                                                                                                  
 cat                                                                                                                                             
-mv                                                                                                                                              
-comm                                                                                                                                            
 cp                                                                                                                                              
+diff                                                                                                                                            
+comm
  • The first file is indicated by —
  • The second file is indicated by +++
  • The first two lines of this output show us information about file 1 and file 2. It lists the file name, modification date, and modification time of each of our files, one per line. 
  • The lines below display the content of the files and how to modify file1.txt to make it identical to file2.txt.
  • - (minus) – it needs to be deleted from the first file.
    + (plus) – it needs to be added to the first file.
  • The next line has two at sign @ followed by a line range from the first file (in our case lines 1 through 4, separated by a comma) prefixed by “-“ and then space and then again followed by a line range from the second file prefixed by “+” and at the end two at sign @. Followed by the file content in output tells us which line remain unchanged and which lines needs to added or deleted(indicated by symbols) in the file 1 to make it identical to file 2

7) Python Testing: Assertions

.assertEqual(a, b)	a == b
.assertTrue(x)	        bool(x) is True
.assertFalse(x)	        bool(x) is False
.assertIs(a, b)	        a is b
.assertIsNone(x)	x is None
.assertIn(a, b)	        a in b
.assertIsInstance(a, b)	isinstance(a, b)

*** .assertIs(), .assertIsNone(), .assertIn(), and .assertIsInstance() all have opposite methods, named .assertIsNot(), and so forth.

Pandas

This is something I have heard about in the past but never used. So this week, as finally decided to write a script to help me to find the peers of flapping ports, learned about pandas from first time. I used another script as “inspiration” and after seeing it was using pandas, I decided to read a bit about it and give it a go.

The main type is the DataFrame. In my head, pandas is just a library to deal with CSV, spreadsheets, etc like when you use a program like libreoffice. And this page, gave me the hints for creating the query I wanted to make.

So at the end I have my very basic script but saves me time logging to each device and find the peer port.

Of course, there are different ways to tackle this problem, but in my environment, the source of truth for links is in a file. You could have that info in the port description too, or in a database, etc.

$ python3 flapping-peer.py -f flapping-list.txt

Result:
SW1 Ethernet1/1 SW2 Ethernet1/1
SW1 Ethernet1/4 SW2 Ethernet1/4

$  
$ cat flapping-list.txt 
SW1,Ethernet1/1
SW2,Ethernet1/4
$
$ cat patching-file.csv 
Site,Source Device,Source Interface,Destination Device,Destination Interface,Media
A,SW1,Ethernet1/1,SW2,Ethernet1/1,SMF
A,SW1,Ethernet1/2,SW2,Ethernet1/2,SMF
A,SW1,Ethernet1/3,SW2,Ethernet1/3,SMF
A,SW1,Ethernet1/4,SW2,Ethernet1/4,SMF
A,SW1,Ethernet1/5,SW2,Ethernet1/5,SMF
$ 

Python Threads

I had to check the reachability of many IPs so I decided to “write” a python script to get this done quickly (yes, I can use nmap but not in this case). I realized that the script was very slow, even just sending two probes…. so I decided to find something else and this was perfect for me. So thanks for the original author as it helped me a lot. I have never tried python threads before so I was quite happy that it worked so smoothly. I adapted for my needs and this is what I have. I remember reading about threads in golang so it helped to understand what it is doing. But likely I will be able to use this as base for more tasks.

As well, I realized that I havent pushed anything in git and that there are extra security layers in place. So I had to create a new token for being able to push my changes to the repo.

Decorators

Trying to make a small change to a python program in my job, I came across something I didnt know in python and only after reading this article (a couple of times) I managed to understand (ask me again in 3 weeks 🙂 The best definition I could find was actually from other blog reference and actually I think it was more clear to me.

“A decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.”

1 – Function returning a function:

In [7]: def greet(name): 
   ...:     return f"Hello, {name}!" 
   ...: def simon(func): 
   ...:     return func("Simon") 
   ...:                                                                                                                       

In [8]: simon(greet)                                                                                                          
Out[8]: 'Hello, Simon!'

simon is a function that has a function as argument, and calls that function with the argument “Simon”. So the function greet is receiving the argument “Simon” and returns a string with that name.

2 – Functions inside other functions:

In [9]: def respect(maybe): 
   ...:     def congrats(): 
   ...:         return "Congrats, bro!" 
   ...:     def insult(): 
   ...:         return "You're silly!" 
   ...:     if maybe == "yes": 
   ...:         return congrats 
   ...:     else: 
   ...:         return insult 
   ...:                                                                                                                       

In [10]: respect("hola")()                                                                                                    
Out[10]: "You're silly!"

In this case, to execute the returned function you need to use “()” at the end (because respect(“hola”) it is a function!): respect(“hola”)()

Keep in mind you return the function “congrats” and it is not executed. If you return “congrats()” then yes, you get the result of executing congrats.

3 – A function that takes another function and defines a function:

In [1]: def startstop(func): 
   ...:     def wrapper(): 
   ...:         print("Starting...") 
   ...:         func() 
   ...:         print("Finished!") 
   ...:     return wrapper 
   ...: def roll(): 
   ...:     print("Rolling on the floor laughing XD") 
   ...: roll = startstop(roll)                                                                                                

In [2]: roll()                                                                                                                
Starting...
Rolling on the floor laughing XD
Finished!

In [3]:        

This case is the same as before, need to use “()” to “execute” roll because it is a function.

4 – With decorator:

In [3]: def startstop(func): 
   ...:     def wrapper(): 
   ...:         print("Starting...") 
   ...:         func() 
   ...:         print("Finished!") 
   ...:     return wrapper 
   ...: @startstop 
   ...: def roll(): 
   ...:     print("Rolling on the floor laughing XD") 
   ...:                                                                                                                       

In [4]: roll()                                                                                                                
Starting...
Rolling on the floor laughing XD
Finished!

In [5]:          

So adding the decorator we avoid writing a line with nested functions. That in a more advanced case, it would make the code easier to read.

You can nest decorators and add arguments too.

python-golang-p1

This week I had to update several spreadsheets…. again donkey job, again try to work smarter. So there was a pattern, and I knew I could copy/paste to the spreadsheet all changes (192 changes per file…). So decided to create a python script to generate the output I needed. It was just new hostnames for devices. So it wasnt really difficult. Although I had to search for basic stuff like how to make a for loop in python. That’s what happens when yo dont use thing often.

Anyway, I managed to get my basic python script. And I could copy paste the output to the spreadsheet just fine.

$ cat rename.py 
for x in range(137,141):
    print("router-p1-r" + str(x) + "01")
    print("router-p1-r" + str(x) + "02")
    print("router-p1-r" + str(x) + "03")
    print()
$ 
$ python rename.py 
router-p1-r13701
router-p1-r13702
router-p1-r13703

router-p1-r13801
router-p1-r13802
router-p1-r13803

router-p1-r13901
router-p1-r13902
router-p1-r13903

router-p1-r14001
router-p1-r14002
router-p1-r14003

But now, I have been trying to learn golang (even though I dont master python neither bash….) and I thought this was a basic stuff to try in golang too. So again, I had to search for basic stuff. How to create a range: link. How to concatenate a string and a integer: link.

So managed to get this and looks like it does the same job:

$ cat rename.go 
package main

import "fmt"

func main() {
	for i := 137; i <= 141; i++ {
		fmt.Println(fmt.Sprint("router-p1-r", i, "01"))
		fmt.Println(fmt.Sprint("router-p1-r", i, "02"))
		fmt.Println(fmt.Sprint("router-p1-r", i, "03"))
		fmt.Println()
	}
}
$ 
$ go run rename.go 
router-p1-r13701
router-p1-r13702
router-p1-r13703

router-p1-r13801
router-p1-r13802
router-p1-r13803

router-p1-r13901
router-p1-r13902
router-p1-r13903

router-p1-r14001
router-p1-r14002
router-p1-r14003

router-p1-r14101
router-p1-r14102
router-p1-r14103

So got the same result in both languages. Keep going!