Golang for Network Ops

Golang for Network Ops

Golang Gopher

Golang for Network Ops

I get asked quite often where the traditional network engineer / network ops should start if they want to broaden their horizons with better code hacking skills or they have spent the last 20 years using Perl scripts or more recently Python and need a change. The answer is easy, Golang. At Socketplane, we all ditched the past couple of years of Java or C and now all code almost exclusively in Go. Go allows us to rapidly develop network solutions around Docker which is written in Go, not to mention incredibly fun to develop in. We have a technology preview up and some really cool new things in development. Now there are many that could care less about the language they use and argue that is merely an implementation detail, the difference to me is if it takes you 3x the time in another language, or there is a performance penalty it is very relevant. That coupled with natively integrated tools, (go fmt, go run -race, go get, go test; etc) puts the productivity through the roof.

One of the creators, Rob Pike (who goes all the way back to Plan 9 at Bell labs) sums up what the goals were when they set out developing Go:

“I’ve said a lot about this since Go came out. In a nutshell, we wanted a language with the safety and performance of statically compiled languages such as C++ and Java, but the lightness and fun of dynamically typed interpreted languages such as Python. It was also important that the result be suitable for large systems software development on modern, networked, multicore hardware. To achieve these goals, we tried to design a language in which the various elements – the type system, the package system, the syntax, concurrency, and so on – were completely “orthogonal”, by which I mean that they never interact in surprising ways, making the language easy to understand but also easy to implement.” – -Rob Pike

Python like interfaces with similar performance as statically typed/linked languages is exactly what most network hackers I know would like. Just as important, is what is left out of the spec and how well if a program compiles it often will result in what you expected and test driven development is lightning fast in Go thanks to the static linking (which also leaves you with a tidy little binary to run or distribute).

The orthogonal nature of go is at the heart of its appropriateness for infra projects. Go doesn’t include the kitchen sink by design. It is intended to be readable, not magical. One of my favorite coding guidelines comes from Docker CTO Solomon Hykes in the Docker Principles that makes Go such a perfect language for platforms. Some criticize go for not having generics. I am actually happy it doesn’t because large collaborative projects with overlay confusing code bases are painful to say the least. Code/Peer reviews are the scalable paths to maintaining code quality, not complexity for the sake of complexity to exclude less then seasoned devs. The following quote is spot on to maintain code coherency (not to mention fun) in large OSS projects and it is reflected in the projects language of choice.

“50 lines of straightforward, readable code is better than 10 lines of magic that nobody can understand.” – -Solomon Hykes

Many of my friends in the network community use Python, but often hit the wall when it comes down to multi-threading due to the global interpreter locking native to Python. You can spin up as many threads as you want but only one is being processed at any given time in order to stay safe. Go uses channels that are basically a sender and receiver that can share data between concurrent threads or “go routines”. This is so much easier then concurrent programming of any other language I have used and not to mention extremely powerful as you can type a channel just as you would any other structure and this includes structs.

Dave Tucker and more of our friends from the networking community will be doing some podcasts, hangouts and eventually meetups for those in NetOps interested in learning more about Go and how it applies to managing infra with a focus on Docker since it is natively written in Go, and well.. awesome. I titled this ‘Golang for Network Ops’ because I think as Rob Pike said, a Python like interface that is compiled to machine code and the associated performance, while still offering convenience of GC (zero latency at that) is perfect for both new and old network hackers alike. I networking performance is king, the same should apply to our tools. So I threw together some simple snippets for those like me who learn by breaking 🙂

Install Go

Download Go from http://golang.org/dl/ and unzip the directory into /usr/local/ on Mac, Fedora or Ubuntu or use installers w/Mac and Windows. The most confusing thing for most is defining a $GOPATH env that points to where your libraries are stored. Instead of requiring a Makefile, you simply keep your libs/code in that path and the Go compiler takes care of the rest when linking.

Install git. yum install git /apt-get install git
Lastly clone a starter project to use:

If the go compiler is not found, make sure it appears in your shells ENV path and the go binary is found like the following from a Mac.

Each of the files have a main() declaration so they can each run standalone for ease for the first timer.

Go Example for Python Devs

Lets do some exec calls. Execs are pretty similar to Python. If you want to perform sysadmin scripts using go it is as easy as Python for doing so.

Package exec runs external commands. It wraps os.StartProcess to make it easier to remap stdin and stdout, connect I/O with pipes, and do other adjustments.

Next lets attempt to resolve some DNS names.

3 Different ways to Define Structs in Go

Structs and Pointers makes Go quite familiar for C programmers. A primary difference in how Go implements pointers is the built in garbage collection native to Go. This means pointers are dynamically dereferenced with zero latency. Zero latency is quite interesting for those who have ever seen a JVM do a massive GC with latency.

The following are three different ways to use structs. This can be familiar for both those coming from both OOP and C style data structures.

Random Pointers

Access control to between packages is like most things in Go, simple yet effective. To export a function, method, interface from a package, you just start the name of it with a capital letter.

The following would be exported and accessible by any package in the project:

While the following is only exported and accessible by the package it resides in only:

At any time you can run go files independant of the directory structure by calling them explicitly as long as there is a main() function and they are in the same package. For example, if you have a struct or function in one file (foo.go) and it is being called from another file that contains a main() execution in (bar.go) you can simply call them both with:

That will avoid any undefined errors from structs/methods/funcs/const etc not located in the same file being explicitly run.

Go Resources

So take a peek and keep an eye out for stuff we will be doing around NetOps, Docker and Go. It will be fun stuff.

Thanks for stopping by, checkout what we are up to at Socketplane and for those in networking, my top three recommendations for learning at the moment are Docker, OVS and Go!

About the Author

Brent SalisburyI have over 15 years of experience wearing various hats from, network engineer, architect, devops and software engineer. I currently have the pleasure of working at the company that develops my favorite software I have ever used, Docker. My comments here are my personal thoughts and opinions. More at Brent's BioView all posts by Brent Salisbury →