<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel><title>Applying DevOps to networks</title><description>Applying DevOps to networks.</description><link>https://netdevops.me/</link><atom:link href="https://netdevops.me/feed_rss_updated.xml" rel="self" type="application/rss+xml" /><managingEditor>Roman Dodin</managingEditor><docs>https://github.com/hellt/netdevops.me</docs><language>en-None</language> <pubDate>Fri, 31 Jan 2025 14:47:24 -0000</pubDate> <lastBuildDate>Fri, 31 Jan 2025 14:47:24 -0000</lastBuildDate> <ttl>1440</ttl> <generator>MkDocs RSS plugin - v1.8.0</generator> <item> <title>Managing multiple Go versions</title> <author>rdodin</author> <category>go</category> <description>&lt;h1&gt;Managing multiple Go versions&lt;/h1&gt;&lt;p&gt;When dealing with several Go projects you inevitably end up needing more than one Go version installed and selected correctly for a given project.&lt;/p&gt;&lt;p&gt;Somehow I always forget how I do this when I need to fix a new version for another project, so here is what I do for the future me:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Install the target release Go downloader. For example, for &lt;code&gt;go1.22.11&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;bashgo install golang.org/dl/go1.22.11@latest&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now download the actual sdk&lt;/p&gt;&lt;p&gt;&lt;code&gt;bashgo1.22.11 download&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now for whatever project that you want to set this version for, create the &lt;code&gt;direnv&lt;/code&gt;&#39;s &lt;code&gt;.envrc&lt;/code&gt; file and set the path accordingly:&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;code&gt;bashPATH=~/sdk/go1.22.11/bin:$PATH&lt;/code&gt;&lt;/p&gt;</description><link>https://netdevops.me/2025/managing-multiple-go-versions/</link> <pubDate>Fri, 31 Jan 2025 14:46:42 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2025/managing-multiple-go-versions/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2025/managing-multiple-go-versions/</guid> </item> <item> <title>Managing multiple kubeconfigs by merging them</title> <author>rdodin</author> <category>kubernetes</category> <description>&lt;h1&gt;Managing multiple kubeconfigs by merging them&lt;/h1&gt;&lt;p&gt;Recently I&#39;ve been deploying k8s clusters on different cloud providers, with different automation stacks and in different configurations. As a result, I ended up with a bunch of of kubeconfigs polluting my &lt;code&gt;~/.kube&lt;/code&gt; directory.&lt;/p&gt;&lt;p&gt;As much as &lt;code&gt;kubectl&lt;/code&gt; is an swiss knife for all things k8s, it still can&#39;t quite make dealing with different kubeconfigs a breeze. The annoying part is that you have to have a single kubeconfig environment with all your clusters, users, contexts listed, and this is not the case when you have multiple kubeconfigs. So, naturally one would want to merge them into a single kubeconfig.&lt;/p&gt;&lt;p&gt;To do that I had to write a small script that does the following high level steps:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Backup existing &lt;code&gt;~/.kube/config&lt;/code&gt; file: you don&#39;t want to lose your existing kubeconfig because you messed up something in your script or overwrote it with a wrong kubeconfig.&lt;/li&gt;&lt;li&gt;Find paths to all kubeconfig files in a particular directory and set them as a &lt;code&gt;KUBECONFIG&lt;/code&gt; environment variable.&lt;/li&gt;&lt;li&gt;merge these kubeconfigs into a single &lt;code&gt;~/.kube/config&lt;/code&gt; file.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Here is the script:&lt;/p&gt;&lt;p&gt;&lt;code&gt;bashcp ~/.kube/config ~/.kube/bak/config_$(date +&#34;%Y-%m-%d_%H:%M:%S&#34;)_bak &amp;amp;&amp;amp; \KUBECONFIG=$(find ~/.kube/cluster_configs -type f | tr &#39;\n&#39; &#39;:&#39;) \kubectl config view --flatten &amp;gt; ~/.kube/config&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Nothing fancy, but it does the job. Essentially the rule of thumb that I follow now is to keep all my kubeconfigs in &lt;code&gt;~/.kube/cluster_configs&lt;/code&gt; directory and run this script whenever I add or delete a kubeconfig in this directory. The resulting kubeconfig will contain all the contexts from all of the files and I could do &lt;code&gt;kubectl config use-context &amp;lt;context&amp;gt;&lt;/code&gt; to switch between them.&lt;/p&gt;</description><link>https://netdevops.me/2024/managing-multiple-kubeconfigs-by-merging-them/</link> <pubDate>Mon, 24 Jun 2024 18:58:22 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2024/managing-multiple-kubeconfigs-by-merging-them/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2024/managing-multiple-kubeconfigs-by-merging-them/</guid> </item> <item> <title>Setting up a Hugo blog with GitLab and CloudFlare</title> <author>rdodin</author> <category>cloudflare</category> <category>gitlab</category> <category>hugo</category> <description>&lt;h1&gt;Setting up a Hugo blog with GitLab and CloudFlare&lt;/h1&gt;&lt;p&gt;&lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; gets a lot of &lt;a href=&#34;https://www.staticgen.com/hugo&#34;&gt;attention&lt;/a&gt; these days, it is basically snapping at the Jekyll&#39; heels which is still the king of the hill! I don&#39;t know if Hugo&#39; popularity coupled with &lt;strong&gt;the fastest static-site-generator&lt;/strong&gt; statement, but for me &#34;speed&#34; is not the issue at all. A personal blog normally has few hundreds posts, not even close to thousands to be worried about slowness.&lt;/p&gt;&lt;p&gt;Then if it is not for speed then why did I choose Hugo? Because it became a solid product with a crowded community and all the common features available. &lt;em&gt;(To be honest I also got an illusion that one day I might start sharpen my Go skills through Hugo as well)&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;As you already noticed, this blog is powered by &lt;strong&gt;Hugo&lt;/strong&gt;, is running on &lt;strong&gt;GitLab pages&lt;/strong&gt;, with SSL certificate from &lt;strong&gt;CloudFlare&lt;/strong&gt; and costs me &lt;strong&gt;$0&lt;/strong&gt;. And I would like to write down the key pieces that&#39;ll probably be of help on your path to a zero-cost personal blog/cv/landing/etc.&lt;/p&gt;</description><link>https://netdevops.me/2017/setting-up-a-hugo-blog-with-gitlab-and-cloudflare/</link> <pubDate>Mon, 24 Jun 2024 18:50:12 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2017/setting-up-a-hugo-blog-with-gitlab-and-cloudflare/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2017/setting-up-a-hugo-blog-with-gitlab-and-cloudflare/</guid> </item> <item> <title>Building AWS Lambda with Python, S3 and serverless</title> <author>rdodin</author> <category>aws</category> <category>aws lambda</category> <category>boto3</category> <category>python</category> <category>serverless</category> <description>&lt;h1&gt;Building AWS Lambda with Python, S3 and serverless&lt;/h1&gt;&lt;p&gt;Cloud-native revolution pointed out the fact that the microservice is the new building block and your best friends now are Containers, AWS, GCE, Openshift, Kubernetes, you-name-it. But suddenly &lt;em&gt;micro&lt;/em&gt; became not that granular enough and people started talking about &lt;em&gt;serverless functions&lt;/em&gt;!&lt;/p&gt;&lt;p&gt;&lt;img alt=&#34;pic&#34; src=&#34;https://gitlab.com/rdodin/pics/-/wikis/uploads/a115166eb200861e796a0a5a847da8e7/image.png&#34;&gt;&lt;/p&gt;&lt;p&gt;When I decided to step in the serverless property I chose &lt;a href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/welcome.html&#34;&gt;AWS Lambda&lt;/a&gt; as my instrument of choice. As for experimental subject, I picked up one of my existing projects - a script that tracks new documentation releases for Nokia IP/SDN products (which in the past I aggregated at &lt;code&gt;nokdoc.github.io&lt;/code&gt; (now closed)).&lt;/p&gt;&lt;p&gt;Given that not so many posts are going deeper than onboarding a simplest function, I decided to write down the key pieces I needed to uncover to push a &lt;strong&gt;real code&lt;/strong&gt; to the Lambda.&lt;/p&gt;&lt;p&gt;Buckle up, our agenda is fascinating:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;testing basic Lambda onboarding process powered by Serverless framework&lt;/li&gt;&lt;li&gt;accessing files in AWS S3 from within our Lambda with &lt;code&gt;boto3&lt;/code&gt; package and custom AWS IAM role&lt;/li&gt;&lt;li&gt;packaging non-standard python modules for our Lambda&lt;/li&gt;&lt;li&gt;exploring ways to provision shared code for Lambdas&lt;/li&gt;&lt;li&gt;and using path variables to branch out the code in Lambda&lt;/li&gt;&lt;/ul&gt;</description><link>https://netdevops.me/2017/building-aws-lambda-with-python-s3-and-serverless/</link> <pubDate>Mon, 24 Jun 2024 18:50:12 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2017/building-aws-lambda-with-python-s3-and-serverless/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2017/building-aws-lambda-with-python-s3-and-serverless/</guid> </item> <item> <title>Arista EOS gNMI Tutorial</title> <author>rdodin</author> <category>arista</category> <category>gnmi</category> <category>gnmic</category> <category>openconfig</category> <category>yang</category> <description>&lt;h1&gt;Arista EOS gNMI Tutorial&lt;/h1&gt;&lt;p&gt;We were pleasantly surprised by the way community appreciated &lt;a href=&#34;../2020/gnmic.md&#34;&gt;gNMIc&lt;/a&gt; release. Thank you 🙏! That solidifies the fact that a well-formed, documented and easy to use gNMI tool was needed.&lt;/p&gt;&lt;p&gt;Now with gNMIc available to everybody its easy like never before to test gNMI implementation of different routing OSes. And in this post we will get our hands on &lt;strong&gt;Arista vEOS&lt;/strong&gt;.&lt;/p&gt;</description><link>https://netdevops.me/2020/arista-eos-gnmi-tutorial/</link> <pubDate>Mon, 24 Jun 2024 18:50:12 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2020/arista-eos-gnmi-tutorial/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2020/arista-eos-gnmi-tutorial/</guid> </item> <item> <title>Building Web front end for Python scripts with Flask</title> <author>rdodin</author> <category>bootstrap</category> <category>flask</category> <category>python</category> <description>&lt;h1&gt;Building Web front end for Python scripts with Flask&lt;/h1&gt;&lt;p&gt;Recently I revived my relationship with Python in an effort to tackle the routine tasks appearing here and there. So I started to write some &lt;em&gt;pocket scripts&lt;/em&gt; and, luckily, was not the only one on this battlefield - my colleagues also have a bunch of useful scripts. With all those code snippets sent in the emails, cloned from the repos, grabbed on the network shares... I started to wonder how much easier would it be if someone had them all aggregated and presented with a Web UI for a shared access?&lt;/p&gt;&lt;p&gt;Thus, I started to build web front-end to the python scripts we used daily with these goals in mind:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;allow people with a zero knowledge of Python to use the scripts by interacting with them through a simple Web UI;&lt;/li&gt;&lt;li&gt;make script&#39;s output more readable by leveraging CSS and HTML formatting;&lt;/li&gt;&lt;li&gt;aggregate all the scripts in one a single repo but in a separate sandboxed directories to maintain code manageability.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This short demo should give you some taste of what it is:&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/KzOFlFYucvM&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34; allowfullscreen&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I am nowhere near even a professional python or web developer. And what makes it even worse is that I used (a lot) a very dangerous coding paradigm - SDD - Stack Overflow Driven Development. So, hurt me plenty if you see some awful mistakes.&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/hellt/PLAZA&#34;&gt;Project source code&lt;/a&gt;&lt;/p&gt;</description><link>https://netdevops.me/2016/building-web-front-end-for-python-scripts-with-flask/</link> <pubDate>Mon, 24 Jun 2024 18:50:12 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2016/building-web-front-end-for-python-scripts-with-flask/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2016/building-web-front-end-for-python-scripts-with-flask/</guid> </item> <item> <title>Using skopeo container image</title> <author>rdodin</author> <category>skopeo</category> <description>&lt;h1&gt;Using skopeo container image&lt;/h1&gt;&lt;p&gt;By now you know I hate to &#34;install&#34; things on the systems I work on, and that is because I have too many machines I carry work on. Hence, I prefer to containerize all the things and use handy aliases.&lt;/p&gt;&lt;p&gt;Here is one for skopeo to copy images between registries:&lt;/p&gt;&lt;p&gt;&lt;code&gt;bashalias skopeo=&#39;sudo docker run --rm \-v ~/.config/gcloud:/root/.config/gcloud:ro \-v ~/.docker/config.json:/tmp/auth.json:ro \-v /var/run/docker.sock:/var/run/docker.sock \-v /usr/bin/docker-credential-gcr:/usr/bin/docker-credential-gcr \-v $(pwd):/workdir \-w /workdir \quay.io/skopeo/stable:v1.14&#39;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;bash$ skopeo --versionskopeo version 1.14.2&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Note this quirky &lt;code&gt;docker-credential-gcr&lt;/code&gt; binary mount, this is an authentication helper for skopeo to authenticate with GCP.Other clouds might require other helpers or file mounts.&lt;/p&gt;&lt;p&gt;A nice blog post on how to use skopeo different transports - &lt;a href=&#34;https://www.redhat.com/sysadmin/7-transports-features&#34;&gt;https://www.redhat.com/sysadmin/7-transports-features&lt;/a&gt;&lt;/p&gt;</description><link>https://netdevops.me/2024/using-skopeo-container-image/</link> <pubDate>Wed, 13 Mar 2024 09:36:57 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2024/using-skopeo-container-image/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2024/using-skopeo-container-image/</guid> </item> <item> <title>Adding border to the logos</title> <author>rdodin</author> <category>blogging</category> <description>&lt;h1&gt;Adding border to the logos&lt;/h1&gt;&lt;p&gt;It is super easy nowadays to generate a decent logo for your OSS project using any of genAI tool (dall-e, bing, etc). But one of the side-effects of the image generation might be the noise around the edges.&lt;/p&gt;&lt;p&gt;If that&#39;s your case you can apply a border (offset) to your logo to mask the potential rough edges. I can recommend &lt;a href=&#34;https://borderize.com/&#34;&gt;borderize&lt;/a&gt; service that makes it a matter of a few clicks.&lt;/p&gt;</description><link>https://netdevops.me/2024/adding-border-to-the-logos/</link> <pubDate>Thu, 15 Feb 2024 22:32:16 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2024/adding-border-to-the-logos/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2024/adding-border-to-the-logos/</guid> </item> <item> <title>Formatting bash</title> <author>rdodin</author> <category>bash</category> <description>&lt;h1&gt;Formatting bash&lt;/h1&gt;&lt;p&gt;Whenever I need to format &lt;code&gt;bash&lt;/code&gt; scripts I use the mvdan&#39;s shfmt - &lt;a href=&#34;https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd&#34;&gt;https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd&lt;/a&gt; as a docker container:&lt;/p&gt;&lt;p&gt;&lt;code&gt;bashsudo docker run --rm -u &#34;$(id -u):$(id -g)&#34; -v $(pwd):/mnt -w /mnt mvdan/shfmt:v3 -w utils/if-wait.sh&lt;/code&gt;&lt;/p&gt;</description><link>https://netdevops.me/2024/formatting-bash/</link> <pubDate>Mon, 05 Feb 2024 09:34:32 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2024/formatting-bash/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2024/formatting-bash/</guid> </item> <item> <title>Upscaling images</title> <author>rdodin</author> <category>blogging</category> <description>&lt;h1&gt;Upscaling images&lt;/h1&gt;&lt;p&gt;You know how in TV shows with IMDB rating ranging from 5 to 7 cops use that magic image recognition software that transforms the cctv image of a bad guy from the &#34;mashed potato&#34; quality to the Vogue cover? Yeah...&lt;/p&gt;&lt;p&gt;But recently I needed to upscale the AI generated logo I made for Clabernetes project, and the quality was &#34;meh&#34;, since it was a free service from Bing and whatnot. So whilst it was printable, the DPI was not good enough. So I decided to try my luck and google for these AI-powered image upscale services; frankly, my hopes were quite low.&lt;/p&gt;&lt;p&gt;The first hit with a fishy DNS name - https://www.upscale.media/ - did not reinforce my beliefs that this is all a gimmick. But I tried, and it was legit good. It upscaled my logo while removed the noise and blurriness from the original image.&lt;/p&gt;&lt;p&gt;Here is the comparison:&lt;/p&gt;&lt;p&gt;&lt;img alt=&#34;upscale&#34; src=&#34;https://gitlab.com/rdodin/pics/-/wikis/uploads/11d7dd09af1c82d31cf6ced1fd70e28b/image.png&#34;&gt;&lt;/p&gt;&lt;p&gt;So yeah, something I wanted to save here because I will likely use it next time as well.&lt;/p&gt;</description><link>https://netdevops.me/2024/upscaling-images/</link> <pubDate>Wed, 31 Jan 2024 16:18:06 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2024/upscaling-images/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2024/upscaling-images/</guid> </item> <item> <title>Creating Google Cloud Platform Function with Python and Serverless</title> <author>rdodin</author> <category>gcp</category> <category>gcp function</category> <category>python</category> <category>serverless</category> <description>&lt;h1&gt;Creating Google Cloud Platform Function with Python and Serverless&lt;/h1&gt;&lt;p&gt;Two years ago &lt;a href=&#34;../2017/nokdoc_sentinel_lambda.md&#34;&gt;I shared&lt;/a&gt; my experience on building the AWS Lambda function for a python project of my own. And a few days ago I stumbled upon a nice opensource CLI tool that I immediately wanted to transform in a web service.&lt;/p&gt;</description><link>https://netdevops.me/2019/creating-google-cloud-platform-function-with-python-and-serverless/</link> <pubDate>Thu, 11 Jan 2024 09:29:38 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2019/creating-google-cloud-platform-function-with-python-and-serverless/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2019/creating-google-cloud-platform-function-with-python-and-serverless/</guid> </item> <item> <title>Creating a Bootstrap based front-end for your simple REST service</title> <author>rdodin</author> <category>bootstrap</category> <category>frontend</category> <category>javascript</category> <description>&lt;h1&gt;Creating a Bootstrap based front-end for your simple REST service&lt;/h1&gt;&lt;p&gt;Not a single day goes by without me regretting I haven&#39;t mastered any front-end technology like React/Angular or the likes. Why would a network engineer want to step into the game that seems orthogonal to its main area of expertise, one might ask?&lt;/p&gt;&lt;p&gt;Truth be told, I wasn&#39;t born with an urge to learn anything that has &lt;em&gt;javascript&lt;/em&gt; under the hood, but over the years, working within the network/backend silos, I realized, that being able to create a simple front-end service is a jewel that fits every crown, no matter what title you wear.&lt;/p&gt;&lt;p&gt;This tutorial is based on the task real task of building up a web interface (&lt;a href=&#34;https://pycatjify.netdevops.me&#34;&gt;pycatjify.netdevops.me&lt;/a&gt;) for the &lt;a href=&#34;serverless-gc-functions.md&#34;&gt;&lt;code&gt;pycatjify&lt;/code&gt;&lt;/a&gt; REST API service deployed as a serverless function. The end result is a &lt;strong&gt;simple&lt;/strong&gt;, completely &lt;strong&gt;free&lt;/strong&gt; and &lt;strong&gt;reusable&lt;/strong&gt; Bootstrap based front-end boilerplate which can be used as a foundation for a similar task.&lt;/p&gt;</description><link>https://netdevops.me/2019/creating-a-bootstrap-based-front-end-for-your-simple-rest-service/</link> <pubDate>Thu, 11 Jan 2024 08:43:15 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2019/creating-a-bootstrap-based-front-end-for-your-simple-rest-service/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2019/creating-a-bootstrap-based-front-end-for-your-simple-rest-service/</guid> </item> <item> <title>OpenStack Client Container Image</title> <author>rdodin</author> <category>docker</category> <category>openstack</category> <description>&lt;h1&gt;OpenStack Client Container Image&lt;/h1&gt;&lt;p&gt;I like the portability, managability and package manager agnostic nature of container images. Especially for the tools I use couple of times a month. And even more so for Python tools that don&#39;t have native wheels for all their dependencies. Like OpenStack Client.&lt;/p&gt;&lt;p&gt;So I built a small &lt;a href=&#34;https://github.com/hellt/dockerfiles/blob/main/openstack-client/openstack-client.dockerfile&#34;&gt;multi-stage Dockerfile&lt;/a&gt; to build a container image with OpenStack Client and all its dependencies. It&#39;s based on the official Python image and has a slim footprint:&lt;/p&gt;&lt;p&gt;&lt;code&gt;Dockerfile--8&amp;lt;-- &#34;https://raw.githubusercontent.com/hellt/dockerfiles/main/openstack-client/openstack-client.dockerfile&#34;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;You can pull the image from &lt;a href=&#34;https://github.com/hellt/dockerfiles/pkgs/container/openstack-client&#34;&gt;ghcr&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;code&gt;docker pull ghcr.io/hellt/openstack-client:6.4.0&lt;/code&gt;&lt;/p&gt;&lt;p&gt;To use this image you first need to source the env vars from your openrc file:&lt;/p&gt;&lt;p&gt;&lt;code&gt;source myopenrc.sh&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Then I prefer to install the alias &lt;code&gt;openstack&lt;/code&gt; to my shell so that it feels like I have the client installed locally:&lt;/p&gt;&lt;p&gt;&lt;code&gt;bashalias openstack=&#34;docker run --rm -it \ -e OS_AUTH_URL=${OS_AUTH_URL} -e OS_PROJECT_ID=${OS_PROJECT_ID} \ -e OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME} \ -e OS_PROJECT_NAME=${OS_PROJECT_NAME} \ -e OS_USERNAME=${OS_USERNAME} -e OS_PASSWORD=${OS_PASSWORD} \ ghcr.io/hellt/openstack-client:6.4.0 openstack $@&#34;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Then you can use the client as usual:&lt;/p&gt;&lt;p&gt;&lt;code&gt;❯ openstack server list+-----------------------------+----------------+--------+-----------------------------+------------------------------+---------------------+| ID | Name | Status | Networks | Image | Flavor |+-----------------------------+----------------+--------+-----------------------------+------------------------------+---------------------+| 0fa75185-0f76-482f-8cc3- | k8s-w3-411e6d7 | ACTIVE | k8s-net-304e6df=10.10.0.11 | nesc-baseimages- | ea.008-0024 || 38e4d60212c8 | | | | debian-11-latest | |-- snip --&lt;/code&gt;&lt;/p&gt;</description><link>https://netdevops.me/2024/openstack-client-container-image/</link> <pubDate>Thu, 11 Jan 2024 08:43:15 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2024/openstack-client-container-image/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2024/openstack-client-container-image/</guid> </item> <item> <title>Flask application in a production-ready container</title> <author>rdodin</author> <category>docker</category> <category>flask</category> <category>nginx</category> <category>uwsgi</category> <description>&lt;h1&gt;Flask application in a production-ready container&lt;/h1&gt;&lt;p&gt;Flask documentation &lt;a href=&#34;https://flask.palletsprojects.com/en/2.3.x/tutorial/deploy/#run-with-a-production-server&#34;&gt;is very clear&lt;/a&gt; on where is the place for its built-in WSGI application server:&lt;/p&gt;&lt;p&gt;!!!note When running publicly rather than in development, you should not use the built-in development server (flask run). The development server is provided by Werkzeug for convenience, but is not designed to be particularly efficient, stable, or secure.&lt;/p&gt;&lt;p&gt;So how about I share with you a &lt;a href=&#34;https://github.com/hellt/nginx-uwsgi-flask-alpine-docker&#34;&gt;&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/a&gt; that will enable your Flask application to run &lt;strong&gt;properly&lt;/strong&gt; and ready for production-like deployments? As a bonus, I will share my findings discovered along the way of building this container image.&lt;/p&gt;&lt;p&gt;&lt;img alt=&#34;nginx-uwsgi-flaks-alpine-docker&#34; src=&#34;https://gitlab.com/rdodin/netdevops.me/uploads/e893ab9ea824ed501170908377d3fb52/image.png&#34;&gt;&lt;/p&gt;</description><link>https://netdevops.me/2017/flask-application-in-a-production-ready-container/</link> <pubDate>Tue, 15 Aug 2023 10:27:14 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2017/flask-application-in-a-production-ready-container/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2017/flask-application-in-a-production-ready-container/</guid> </item> <item> <title>SR OS Rootifier or how to flatten 7750 SR config</title> <author>rdodin</author> <category>nokia</category> <category>sr os</category> <description>&lt;h1&gt;SR OS Rootifier or how to flatten 7750 SR config&lt;/h1&gt;&lt;p&gt;Back in the days when I mostly did routing stuff I spent the whole day configuring SROS devices via SSH. And once in a while I saw that SSH session or its server part (or even underlying connection) glitched, resulting in a corrupted lines feeded to the device.&lt;/p&gt;&lt;p&gt;What was also quite common is to make a mistake (i.e. syntax one) in a single line and watch like the rest of config got applied to the wrong context.&lt;/p&gt;&lt;p&gt;These sad facts pushed me to create a &lt;strong&gt;rootifier&lt;/strong&gt; CLI script, that was converting tree-like SROS config into flattented (aka rooted) fashion.&lt;/p&gt;&lt;p&gt;&lt;img alt=&#34;rootifier&#34; src=&#34;https://gitlab.com/rdodin/netdevops.me/uploads/29184e488b07d8b5efb77d367a9e41ce/image.png&#34;&gt;&lt;/p&gt;&lt;p&gt;!!!note &#34;update 2023&#34; The web service that was available publicly but has been now decommissioned due to the transition to MD-CLI.&lt;/p&gt;</description><link>https://netdevops.me/2017/sr-os-rootifier-or-how-to-flatten-7750-sr-config/</link> <pubDate>Tue, 15 Aug 2023 10:27:14 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2017/sr-os-rootifier-or-how-to-flatten-7750-sr-config/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2017/sr-os-rootifier-or-how-to-flatten-7750-sr-config/</guid> </item> <item> <title>gNMIc joins Openconfig 🚀</title> <author>rdodin</author> <category>gnmi</category> <category>gnmic</category> <category>openconfig</category> <description>&lt;h1&gt;gNMIc joins Openconfig 🚀&lt;/h1&gt;&lt;p&gt;Two years ago, a dozen contributors less, 400 Pull Requests, and 2000 commits behind, another pet project appeared on a vast GitHub landscape. It was a learning exercise by [Karim Radhouani][karim-github] to sharpen his skills in [gNMI][gnmi-ref] - a niche network management protocol promoted by the [Openconfig][oc] group.&lt;/p&gt;&lt;p&gt;Initially named &lt;code&gt;gnmi_client&lt;/code&gt;, it had a noble but narrow scope of providing a feature-rich, complete, yet intuitive CLI for gNMI-enabled routers. Fast forward two years, and we have the [&lt;strong&gt;gNMIc&lt;/strong&gt;][gnmic-main-site] software suite that &lt;strong&gt;is much more than just a CLI&lt;/strong&gt; for gNMI.&lt;/p&gt;&lt;div class=&#34;img-shadow&#34;&gt;&lt;video width=&#34;100%&#34; autoplay muted loop controls&gt;&lt;source src=&#34;https://gitlab.com/rdodin/pics/-/wikis/uploads/d3a08c2f03c2d15db2074967e4ef268f/gnmic-oc.mp4&#34; type=&#34;video/mp4&#34;&gt;&lt;/video&gt;&lt;/div&gt;&lt;p&gt;Today, Nokia donates the gNMIc project to Openconfig, and with that move, we expect to see gNMIc adopted by even more companies and organizations :partying_face:&lt;/p&gt;&lt;div class=&#34;grid cards&#34; markdown&gt;- :material-home:{ .lg .middle } **gNMIc new address** --- :material-github: [openconfig/gnmic][gnmic-repo] :material-book: [https://gnmic.openconfig.net][gnmic-main-site]&lt;/div&gt;&lt;p&gt;In this post I&#39;d like to give you a brief overview of gNMIc&#39;s core features and share my thoughts on what we expect to happen with gNMIc moving under the Openconfig&#39;s wing.&lt;/p&gt;</description><link>https://netdevops.me/2022/gnmic-joins-openconfig-/</link> <pubDate>Tue, 15 Aug 2023 10:19:41 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2022/gnmic-joins-openconfig-/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2022/gnmic-joins-openconfig-/</guid> </item> <item> <title>Test coverage for Go integration tests</title> <author>rdodin</author> <category>containerlab</category> <category>go</category> <category>testing</category> <description>&lt;h1&gt;Test coverage for Go integration tests&lt;/h1&gt;&lt;p&gt;I have been working on &lt;a href=&#34;https://containerlab.dev&#34;&gt;containerlab&lt;/a&gt; for a while now; a project that once started as a simple idea of a tool that would create and wire up SR Linux containers grew into a full-blown network emulation tool loved by the community and used in labs by many.&lt;/p&gt;&lt;p&gt;As it became evident that many more users started to rely on containerlab for their daily work, the looming feeling of responsibility for the quality of the tool started to creep in. At the same time, the growing user base exposed us to many more feature requests and integrations, making it harder to find time to address technical debt and improve testing.&lt;/p&gt;&lt;p&gt;Given the nature of the project, it was clear that integration tests offer a quick way to validate the functionality, as we could replicate the user&#39;s workflow and verify the outcome. However, the integration tests are not without their own challenges, and one of them is the test coverage which is not as easy to get as with unit tests.&lt;/p&gt;&lt;p&gt;In this post, I will share how coverage enhancements introduced in Go 1.20 helped us to get the coverage for our integration tests and jump from a miserable 20% to a (less sad) 50%.&lt;/p&gt;</description><link>https://netdevops.me/2023/test-coverage-for-go-integration-tests/</link> <pubDate>Tue, 15 Aug 2023 10:01:20 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2023/test-coverage-for-go-integration-tests/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2023/test-coverage-for-go-integration-tests/</guid> </item> <item> <title>Getting XML data sample for a given leaf in a YANG model</title> <author>rdodin</author> <category>docker</category> <category>netconf</category> <category>yang</category> <description>&lt;h1&gt;Getting XML data sample for a given leaf in a YANG model&lt;/h1&gt;&lt;p&gt;We can praise YANG as long as we want, but for an end user YANG is useful as the tooling around it and the applications leveraging it. Ask yourself, as a user of any kind of NETCONF/YANG application what was the last time you looked at a &lt;code&gt;*.yang&lt;/code&gt; file content and found something that was needed to consume that application?&lt;br&gt;In a user role I personally never look at a YANG source, though, I look at the tree or HTML representation of YANG all the time; Thats is the YANG human interface for me.&lt;/p&gt;&lt;p&gt;And even in these human friendly formats you can&#39;t find all the answers; for example, looking at the YANG tree, how do you get the XML data sample of a given leaf? Thats what we will discover in this post.&lt;/p&gt;</description><link>https://netdevops.me/2020/getting-xml-data-sample-for-a-given-leaf-in-a-yang-model/</link> <pubDate>Tue, 21 Mar 2023 20:01:39 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2020/getting-xml-data-sample-for-a-given-leaf-in-a-yang-model/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2020/getting-xml-data-sample-for-a-given-leaf-in-a-yang-model/</guid> </item> <item> <title>NETCONF subtree filtering by example</title> <author>rdodin</author> <category>netconf</category> <description>&lt;h1&gt;NETCONF subtree filtering by example&lt;/h1&gt;&lt;p&gt;If you pick a random NetEng and ask them if they love NETCONF they would likely say &#34;Nah&#34;. The ~~hate-hate~~ love-hate kind of relationship with NETCONF mostly roots in its XML layer that one can&#39;t swap out. But if we set the XML-related challenges aside, it will become clear that NETCONF is a very well designed management interface with lots of capabilities. &lt;/p&gt;&lt;p&gt;In this topic we will touch on the NETCONF&#39;s subtree filtering capabilities.&lt;/p&gt;</description><link>https://netdevops.me/2020/netconf-subtree-filtering-by-example/</link> <pubDate>Tue, 21 Mar 2023 19:44:31 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2020/netconf-subtree-filtering-by-example/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2020/netconf-subtree-filtering-by-example/</guid> </item> <item> <title>BGP VPLS deep dive. Nokia SR OS &amp; Juniper</title> <author>rdodin</author> <category>bgp</category> <category>juniper</category> <category>nokia</category> <category>vpls</category> <description>&lt;h1&gt;BGP VPLS deep dive. Nokia SR OS &amp;amp; Juniper&lt;/h1&gt;&lt;p&gt;It may very well be that VPLS days are numbered and EVPN is to blame. Nevertheless, it would be naive to expect VPLS extinction in the near future. With all its shortcomings VPLS is still very well standardized, interop-proven and has a huge footprint in MPLS networks of various scale.&lt;/p&gt;&lt;p&gt;In this post I will cover theory and configuration parts for one particular flavor of VPLS signalling - BGP VPLS (aka Kompella VPLS) defined in &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc4761&#34;&gt;RFC4761&lt;/a&gt;. I&#39;ll start with simple single home VPLS scenario while multi-homing techniques and some advanced configurations might appear in a separate post later.&lt;/p&gt;&lt;p&gt;In this topic the following SW releases were used:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Nokia (Alcatel-Lucent) VSR 14.0.R4&lt;/li&gt;&lt;li&gt;Juniper vMX 14.1R1.10&lt;/li&gt;&lt;/ul&gt;</description><link>https://netdevops.me/2016/bgp-vpls-deep-dive-nokia-sr-os--juniper/</link> <pubDate>Tue, 21 Mar 2023 19:44:31 +0000</pubDate><source url="https://netdevops.me/feed_rss_updated.xml">Applying DevOps to networks</source><comments>https://netdevops.me/2016/bgp-vpls-deep-dive-nokia-sr-os--juniper/#__comments</comments><guid isPermaLink="true">https://netdevops.me/2016/bgp-vpls-deep-dive-nokia-sr-os--juniper/</guid> </item> </channel></rss>