SV650s with Heterochromea

This evening I decided to pull the front fairing on my Suzuki SV650s off the bike to change the right front blinker. I had read up on how to do the disassembly from SVRider.com and had some vague notions:

  • gather my metric allen wrenches and my screwdrivers
  • remove the mirrors
  • remove the top two screws holding the windscreen (because they attach to the part of the cowl that is attached to the frame).
  • remove about 4 other bolts

And the front cowl comes right off…. right? More or less.

It took longer than the 15 minutes that the pros quoted. Partly because I am not accustomed to working with my hands and partly because the cheap allen wrench I had purchased from Lowe’s started falling apart while I was in the disassembly phase.

You need an allen wrench to properly re-assemble it. Sigh… I made do with a screwdriver and grit.

After sucessfully removing the fairing and changing the blinker, it turned out that the harness connector has changed since the bike was manufactured. Maybe the fact that the lens was a different color should have been a clue. Because I pulled the battery out to be charged I won’t know until tomorrow whether I have it wired correctly.

Do I know if I did it right? Nope!

But do I feel satisfied with working on it? You bet!

10 Ways to Keep Perspective and Avoid Stress and Anger

I’m an intense type A kind of person. I admit that. There aren’t many things that I want to do halfway when I start doing them. I want to own mastery over the things that I choose.

But I have my ways of being relaxed and groovy too. I struggled with anger a lot as a teenager and I had to come up with a lot of skills to deal with that and as it turns out, most of them have to do with keeping perspective. So I present to you this list of mental techniques I use to be sure I can be a chill dude while I am pursuing whatever ambitions I have.

  1. Remember: Whatever your journey, the destination is the same. In the end, we will all be dead. :) So try not to be outcome-oriented and instead, be experience-oriented. Make the most of your current experience by looking at what is around you and keeping your focus on the things that make you enjoy this moment. Use your eyes and your ears. Make small-talk with people rather than whipping out your phone. Enjoy the breeze, the trees, and your cranky knees.
  2. Give priority to your physical needs and comfort. Unless you’re presently engaged in endurance training of some sort, don’t let yourself get too hungry or hot or cold. Take bathroom breaks. You can enjoy your moments better when you aren’t distracted by the physical demands of being a human.
  3. Say No. If you’re saying yes to everything you will be over-committed. For any given moment of your life you will have to decide what your goals are and say “yes” to the things that align and “no” to the things that don’t. Time is limited. In choosing your goals, give intrinsic motivators (e.g. what you notice you have endless tenacity about) priority over extrinsic motivators (e.g. status in the community).
  4. Permit yourself to change your mind. And permit yourself to apologize. We are not omniscient beings and no one that we should reasonably care about expects this of us. But a good attitude and a verbal recognition that what you do matters to other people will always be appreciated.
  5. Avoid scheduling things back to back and and give yourself plenty of time to get places and/or collect your thoughts and prepare. Giving yourself time to think between engagements is valuable stress management.
  6. When driving… Treat every drive like a leisurely cruise on the boulevard. Think to yourself out loud: “there is no rush… what a nice day!”. Even if you are late. Give yourself the gift of a large following distance to the car in front of you. Around 5-7 seconds is good during non-rush hours… 3 seconds or more during rush. Don’t tailgate! Invite people to lane change ahead of you. Let people drive faster than you. Maybe they are poor fools that haven’t read #1.
  7. With other people… Remember that misunderstandings are commonplace. Extend to them an assumption of good intent and ask people to repeat or restate things that make you feel offended or defensive.
  8. Permit yourself to decide that some people are not worth your time. This includes dishonest people, negative people, and people who make their emotional needs the responsibility of everyone but themselves. Choose to deal with these people as little as possible.
  9. For stuck-on-the-phone with customer service scenarios, if you can’t seem to make sense of or make yourself understood to the person on the other end of the phone, ask for someone else. It doesn’t have to be unpleasant or upsetting. And you might get lucky and land with someone who is genuinely helpful and interested.
  10. Don’t run your budget too lean. If you’re spending close to what you’re making and living paycheck to paycheck, you will feel stress when bills come due. Keep extra money in savings so you don’t overdraw and spend drastically less than you make. Incidentally, this is a metaphor for nearly everything else on this list.

It was hard work coming up with this list. The examples are all over the map. But I hope that reading it helps you to keep perspective and enjoy your moments more.

Today’s message is for those who don’t know exactly what their passions are. Don’t worry about it. You might consider to instead aggressively pursue ambitious short term goals. You learn a lot in the process, forge strong relationships with the people you work with, and it leaves you open to pursue that shiny thing you are more likely to notice in the periph of your field of vision.
— My wording, but the short-term-goal bit is from musician-comedian Tim Minchin

Kicking off My Mini-Sabbatical... Why I Left and What I Want to Build

I left my position at Juniper on Friday. It was a happy-but-bittersweet parting because I really liked my team there. I received good cheer and wishes for great success and votes of confidence from nearly everyone. It’s really heartwarming and I get a bit misty thinking about it.

People who know me in my life as a computer geek know me as the network guy who will use any excuse to write another script. This is true. I’ve always been fascinated with the power of computers to allow a person to do more than he would be capable of alone. They say time is money. I say that well-directed code is time.

At early points in my career I remembering adding VBA logic to my Word and Excel documents and developing templates in Visio to make my workflow easier. This is the same thing as what I do as a network engineer: Remove the boredom of repetition.

Repetition does have a purpose. I used a lot of it when I was preparing for my JNCIE-SP exam. With a little study, I already knew the concepts for that test. The rest was a matter of practice and getting faster at doing things.

But once you have achieved the goal of learning or habituating something unfamiliar, the repetition no longer serves a purpose to you and it starts to make sense to code it away. This has always been a part of my work. When I am being self-deprecating and humorous, I say it is because I am “lazy”. When I am glorifying myself, I say I’m working “smarter”. The truth is somewhere in the middle.

I am moving on to join Salesforce.com to steep myself in the datacenter environment and to help them to build systems that will deploy and support their networks. For all of the scripts that I have written so far, they have managed to be useful tools with longevity but have not yet added up to a sustainable and supportable system that would stand long after I leave. This is what I hope to achieve.

This is an exciting time for me and other code-friendly network operators/engineers/architects. And it is a tough challenge to tackle. A lot of systems people consider the network as a black box, as a given, as a fundamental requirement that you do not mess with. Indeed, even some level of network state is required to configure the network devices effectively.

People often wonder in their blogs why the network has lagged servers in becoming agile, virtualized, and orchestrated. But servers couldn’t have become virtualized and orchestrated without the network already there connecting everything.

So deploying servers depends on the network being there. And complex network deployment depends on the of the network being there. This makes deploying the final network state a meta-problem. How do you deploy the network and guarantee you’re not breaking it and your ability to fix it? How do you change state as frequently as needed without killing your network devices by a thousand tiny cuts?

I don’t feel defeated by these thoughts. These are the challenges. These are the interesting sorts of problems to solve. And I intend to spend part of this week thinking about it, and part of it resting, and part of it just reading, and part of it writing posts like this one.

See you soon.

-Franco

I just removed my work e-mail and contacts from my phone and a lot of contacts disappeared. Remember to set the Default Account for your Contacts so that they go some place that sticks with you!

When troubleshooting Junos class-of-service for aggregated interface bundles, always check the memberlinks too.
— me

Fetching Configuration Subtrees Using Netconf

It took me a bit of struggling to figure out how to pull configuration subtrees via NetConf. Part of this was because I was using tags instead of . But also, I was hitting 256 character line-limits.

I’ll work that out later… the main reason for this post is to document what I found on how to get configuration subtrees. This particular example fetches the subtree for a specific neighbor under [protocols l2circuit].

To structure the rpc request, we use the command “get-config” and specify a source of candidate. Then we add a “filter” tag with an attribute of @type=“subtree” and under that we can specify the configuration subtree as xml tags.

<rpc message-id="1002 Tue Jun 17 23:25:48 -0400 2014">
    <get-config>
        <source><candidate/></source>
        <filter type="subtree">
            <configuration>
                <protocols>
                    <l2circuit>
                        <neighbor>
                            <name>192.168.104.69</name>
                        </neighbor>
                    </l2circuit>
                </protocols>
            </configuration>
        </filter>
    </get-config>
</rpc>
]]>]]>

This is the reply I got.

rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.3R4/junos" message-id="1002 Tue Jun 17 23:25:48 -0400 2014">
    <get-config>
        <source><candidate/></source>
        <filter type="subtree">
            <configuration>
                <protocols>
                    <l2circuit>
                        <neighbor>
                            <name>192.168.104.69</name>
                        </neighbor>
                    </l2circuit>
                </protocols>
            </configuration>
        </filter>
    </get-config>
</rpc>
<data>
<configuration xmlns="http://xml.juniper.net/xnm/1.1/xnm" junos:changed-seconds="1402600329" junos:changed-localtime="2014-06-12 19:12:09 UTC">
    <protocols>
        <l2circuit>
            <neighbor>
                <name>192.168.104.69</name>
                <interface>
                    <name>ae0.3909</name>
                    <virtual-circuit-id>55509</virtual-circuit-id>
                </interface>
                <interface>
                    <name>ae0.3933</name>
                    <virtual-circuit-id>55533</virtual-circuit-id>
                </interface>
                <interface>
                    <name>ae0.3959</name>
                    <virtual-circuit-id>55559</virtual-circuit-id>
                </interface>
                <interface>
                    <name>ae0.3983</name>
                    <virtual-circuit-id>55583</virtual-circuit-id>
                </interface>
                <interface>
                    <name>ae0.3991</name>
                    <virtual-circuit-id>55591</virtual-circuit-id>
                </interface>
            </neighbor>
        </l2circuit>
    </protocols>
</configuration>
</data>
</rpc-reply>
]]>]]>

My particular application in this case was that I wanted to get the interface associated with a certain virtual-circuit-id and neighbor. This made it easy to collect what I wanted and to also present the xml for logging.

Garbled Text for Tree -- Ubuntu/Putty/UTF-8

I use putty at home to connect to my Ubuntu VMs for development and I was getting garbled output for tree.

fluong@ubuntu:~/pyjnx$ tree
.
âââ auth
â   âââ __init__.py
â   âââ __init__.pyc
â   âââ userpass.py
â   âââ userpass.pyc

I did some searching and found this solution: setting UTF-8 remote character set for putty.

Now everything is pretty and I am happy.

fluong@ubuntu:~/pyjnx$ tree
.
├── auth
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── userpass.py
│   └── userpass.pyc

Data Center Networking @ Facebook by David Swafford

I’ve been looking into data center fabrics and how you handle the scale of large networks lately so I decided I should take some time today to fully view the presentation(video and PDF) by David Swafford which he did at NANOG 59 late last year.

I met David Swafford when Facebook came to town for MPLS 2013. He was a really cool guy. I was inspired even at the time by hearing the way that they are going about support their networks. Very smart!

I took away a lot of nuggets from watching it. Here are a few:

  • Assume we can’t trust any rack
  • We can’t trust networking boxes either
  • Backbone devices are powerful in the wrong ways for a data center. They can handle many routes but don’t have the desired port density.
  • Going from 2 large leaf switches to many smaller leaf switches allows you to move from 1+1 to N+1.
  • Beware of silent failures by complex networking devices. They are hard to detect, BTW.
  • Automating ToR switch upgrades and handing a “push-button” interface to the service owners helped to remove the roadblocks for full upgrades of ToR switches. (I found it analogous to app upgrades on my phone)
  • They even scripted many parts of the process, such as determining who the on-call is for a given group at a given time. Fascinating.

Monitor all the things:

  • interface statistics and state
  • bgp statistics and state
  • FIBs
  • TCP retransmits

Respond to your Alerts with Automation:

  • FBAR stands for Facebook Automation Remediation
  • Receive Alert, login to device, verify still down, either ignore or remedy.

He also covers a lot of thoughts on engineers that automate:

  • Spend less time doing repetitive tasks
  • Spend more time solving interesting problems or learning

His final challenge: What would you do if you weren’t afraid?

Shared Thoughts on the Path to Network Programmability

I wanted to share a really well written blog post that is based on a presentation about the evolution of Network Programmability. One of the things I tend to like about a strong presentation is that it covers enough history and current context to make the content relevant to its audience. The writer of this article does that amazingly well. I’m glad to share it since I agree with much of what he said and it dovetails with my thinking on the subject.

Here are some of the points summarized: - We need a new model. We need to put into place a methodology that allows us to interact with the network in the same way that we design it. - Purchasing products or building solutions that do the [high level abstractions], without a mastery of [fundamental technologies],.. will inevitably result in failure. - At scale, repetitive tasks are the not-so-silent killer…. These repetitive tasks tend to occupy a lot of time, mostly for those whose time is really valuable… These tasks are prime candidates for automation. - Some kind of centralization will win out. - No, you do NOT need to become a programmer, but you can if you truly want to. - “The truth is that we don’t need all network engineers to learn code. We need network engineers to solve networking problems. We also need a smaller subset of these folks to tackle the problems in existing tool sets and getting the networking discipline to understand how to improve processes for the better.”

We’re not arguing… I’m just explaining why I’m right!!!
— John Felkins

3 Fallacies That Prevent Network Engineers From Learning Scripting and Automation

3 Fallacies That Prevent Network Engineers From Learning Scripting and Automation

I don’t have enough time right now…

Life feels full. There are constant demands on your time. Maybe you’d feel overwhelmed if you took on just a little bit more. I understand. We’ve all been there. “I just have to get done with XXX and then things will settle down and then I’ll be able to start this new thing.” But will you really be done with project XXX any time soon? Will things really settle down afterward? And if they do, will you remember that there was this thing that you wanted to start?

If we were more honest, we might admit that there is never a perfect time to start some things: Parenting. Working out. Learn to play guitar. Learning a new language.

I’m willing to bet that in your recent past, you were able to find time for shopping for that new iPad, or Television, or Car. You probably didn’t even need to find the exact “right time” to start any of that… you just started it and it got done.

The irony about learning how to code is that your life would be so much less overwhelming if only you had some tools to make your computers do more of the work for you. You have to make a small commitment to get to the point of not being overwhelmed. This has to be paid upfront and there is never a good time to start. But if you look at that from another perspective, if there is never a good time to start, then you can get started any time… right now even!

I don’t know any languages…

This seems like a big stumbling block. You don’t know how to code. At all!

And let’s face it… coding is about as hard as learning to speak a new language. The comparison is apt. And here are some thoughts to challenge the way you think about both:

  1. You have never learned any language by not speaking it.
  2. You have never become fluent in any language in a classroom.
  3. All languages are only learned by immersing yourself in their use.

And to immerse yourself, you have to embrace discomfort. And you have to do this often enough until it is not awkward. My advice to those who want to start learning a new language is to just start speaking it and let yourself be awkward for the first bit. Wanna learn to code? Just start writing code.

I don’t know how to begin…

If you are being held back by this thought, you are close to starting. Especially if you ask yourself or people around you how to begin. Or, more specifically, “What’s the smallest step I can take today to code?”.

Start small. Your first bit of code doesn’t even have to be useful.

Anticipate frustration and persist a little bit. When you encounter frustration, set a timer for 10 minutes during which time you will perform google searches for similar examples and try to mimic the examples to get things to work for whatever your current small project is. Then reward yourself with a break.

Make it a new habit. Use your new language skills a little each day. Those skills are either in growth or decay. You need to keep them growing.

Don’t overdo it and burn out.

Building Blocks toward Network Device Scripting

Here is a collection of building block steps I have used to get started:

  1. Learn a language
  2. Script login to a router using SSH
  3. Collect “Show Version” using SSH
  4. Script a configuration add to a router.
  5. Have your script isolate the line containing the version number of the router.
  6. Have your script isolate the text of the version number of the router.
  7. Use regular expressions to check that the version of the router is some expected value.
  8. Write a script to upload/download files to/from the router
  9. Learn XML and XPATH
  10. Script a login to a router using NetConf over SSH
  11. Using NetConf, get the version, config, hardware inventory of a router

I used these steps and assembled an API for TCL/EXPECT which will make steps 1-10 pretty darn easy.

Scratch Notes on Benevolent Self-Interest

  • On a grand scale, no one else can figure out what you need to take care you.
    • Secure your own mask before helping others with theirs.
    • Self-interest gets a bad rap when the range is lop-sided. When we see a person destroying their long-term goals (and maybe those of others) in pursuit of the short-term gain, it’s hard to feel like this person is doing justice to himself/herself or the world. Self-interest is often benevolent when the range of a person’s actions are not lop-sided.
    • It is easier to trust a person when you can understand how they benefit from their own actions and that it isn’t at your expense.
    • Self-interest doesn’t preclude and often includes concern for the well-being of your associates and respect for those engaged in a similar struggle.
    • Two people engaged in a relationship that don’t speak their minds will find that the relationship will reach a point of frustrating mediocrity. You have to represent your perspective, your likes, and your interests. You have to take positions and be willing to revise them.
    • Free-Market Capitalism, the political philosophy of self-interest-therefore-liberty, has done more for the poor than the altruistic and tyrannical political philosophies.

Every American understands these things on some gut level but a lot of Americans struggle with being identified as self-interested.

Unit testing with tcltest

Thanks to a very helpful online blog tutorial, I was able to get going with some real unit testing for my juniper-helpers library on github. This is going to be very handy to have.

  fluong@ubuntu:~/juniper-helpers/test$ ./all.tcl
  Tests running in interp:  /usr/bin/tclsh8.5
  Tests located in:  /home/fluong/Dropbox/code/juniper-helpers/test
  Tests running in:  /home/fluong/Dropbox/code/juniper-helpers/test
  Temporary files stored in /home/fluong/Dropbox/code/juniper-helpers/test
  Test files run in separate interpreters
  Running tests that match:  *
  Skipping test files that match:  l.*.test
  Only running test files that match:  *.test
  Tests began at Sun Mar 09 21:22:38 EDT 2014
  gen.tcl.test
  ++++ range_1_1 PASSED
  ++++ range_1_2 PASSED
  ++++ range_1_10 PASSED
  ++++ range_2_10_2 PASSED
  ++++ ipv4_count_0 PASSED
  ++++ ipv4_count_1 PASSED
  ++++ test_ipv4_1024_incr_third_octet PASSED
  textproc.tcl.test
  ++++ nsplit_single_line PASSED
  ++++ nsplit_basic_1 PASSED
  ++++ njoin_single_item PASSED
  ++++ njoin_basic_1 PASSED
  ++++ nrange_0_0 PASSED
  ++++ nrange_0_1 PASSED
  ++++ nrange_end PASSED

  Tests ended at Sun Mar 09 21:22:38 EDT 2014
  all.tcl:        Total   14      Passed  14      Skipped 0       Failed  0
  Sourced 2 Test Files.

JUNOS - How to Configure an MSTP Instance for VPLS

WARNING: THIS CONFIGURATION DOES NOT WORK AND IS NOT SUPPORTED

Update: Looks like this configuration may not work at all… I may update this post when I get more information. In the meantime, reference: http://www.juniper.net/techpubs/en_US/junos12.3/topics/usage-guidelines/vpns-configuring-vpls-and-integrated-routing-and-bridging.html

Given this vpls config

routing-instances VPLS {
    instance-type vpls;
    interface ge-1/1/0.4000;
    interface ge-1/1/1.4000;
    interface ge-1/1/2.4000;
    interface ge-1/1/3.4000;
    vrf-target target:1:1;
    forwarding-options {
        family vpls {
            flood {
                input VPLS-BUM-POLICER;
            }
        }
    }
    protocols {
        vpls {
            site local-site {
                automatic-site-id;
            }
        }
    }
}

interfaces ge-1/1/XXX {
    flexible-vlan-tagging;
    mtu 9188;
    encapsulation flexible-ethernet-services;
    unit 4000 {
        description "VPLS Instance";
        encapsulation vlan-vpls;
        vlan-id-list 4000-4029;
        family vpls;
    }
}

Here is the MSTP Configuration

routing-instances MSTP {
    instance-type layer2-control;
    /* don't configure interfaces at this level */
    protocols {
        mstp {
            /* don't include units on the interface configs */
            interface ge-1/1/0;
            interface ge-1/1/1;
            interface ge-1/1/2;
            interface ge-1/1/3;
            /* put VLANs you're not interested in another msti instance */
            msti 1 {
                vlan [ 1-3999 4030-4094 ];
            }
        }
    }
}

Show commands will need to have the name of the routing instance added

fluong@victor-wooten> show spanning-tree bridge routing-instance MSTP
Feb 28 18:00:26
STP bridge parameters
Routing instance name               : MSTP
Context ID                          : 2
Enabled protocol                    : MSTP

STP bridge parameters for CIST
  Root ID                           : 32768.5c:5e:ab:d2:73:d2
  CIST regional root                : 32768.5c:5e:ab:d2:73:d2
  CIST internal root cost           : 0
  Hello time                        : 2 seconds
  Maximum age                       : 20 seconds
  Forward delay                     : 15 seconds
  Number of topology changes        : 1
  Time since last topology change   : 820 seconds
  Local parameters
    Bridge ID                       : 32768.5c:5e:ab:d2:73:d2

STP bridge parameters for MSTI 1
  MSTI regional root                : 32769.5c:5e:ab:d2:73:d2
  Hello time                        : 2 seconds
  Maximum age                       : 20 seconds
  Forward delay                     : 15 seconds
  Number of topology changes        : 0
  Local parameters
    Bridge ID                       : 32769.5c:5e:ab:d2:73:d2


fluong@victor-wooten> show spanning-tree interface routing-instance MSTP
Feb 28 18:00:55

Spanning tree interface parameters for instance 0

Interface    Port ID    Designated      Designated         Port    State  Role
                         port ID        bridge ID          Cost
ge-1/1/0        128:51       128:51  32768.5c5eabd273d2     20000  FWD    DESG
ge-1/1/1        128:52       128:51  32768.5c5eabd273d2     20000  BLK    BKUP
ge-1/1/2        128:53       128:53  32768.5c5eabd273d2     20000  FWD    DESG
ge-1/1/3        128:54       128:53  32768.5c5eabd273d2     20000  BLK    BKUP 


fluong@victor-wooten> show spanning-tree mstp configuration routing-instance MSTP
Feb 28 18:01:13
MSTP configuration information
Context identifier     : 2
Revision               : 0
Configuration digest   : af:0c:a9:14:79:da:16:86:71:e3:ae:cd:7b:00:d4:63


MSTI     Member VLANs                                                      
   0      0,4000-4029                                                     
   1      1-3999,4030-4094