<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[MediocreDevOps]]></title><description><![CDATA[I'm a mediocre DevOps person who goes down rabbit holes.]]></description><link>https://blog.mediocredevops.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 12 May 2026 09:28:31 GMT</lastBuildDate><atom:link href="https://blog.mediocredevops.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building a Not-so-portable ARM tablet with Khadas Edge 2]]></title><description><![CDATA[As the title says I'm documenting my entire Khadas Edge 2 journey. I'm a huge fan of tablets. I like the screen size they come with and the features.
But is it perfect to replace my day-to-day machine? Heck no. I run containers and kubernetes and wha...]]></description><link>https://blog.mediocredevops.com/building-a-not-so-portable-arm-tablet-with-khadas-edge-2</link><guid isPermaLink="true">https://blog.mediocredevops.com/building-a-not-so-portable-arm-tablet-with-khadas-edge-2</guid><category><![CDATA[khadasedge2]]></category><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[ARM]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Sun, 21 Jul 2024 11:15:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1721560455819/b501ebac-1e13-418f-8268-95796c8a3313.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As the title says I'm documenting my entire Khadas Edge 2 journey. I'm a huge fan of tablets. I like the screen size they come with and the features.</p>
<p>But is it perfect to replace my day-to-day machine? Heck no. I run containers and kubernetes and what not. So the web vscode might be a really good option.</p>
<p>I got the khadas edge a year or so ago and I've not been able to figure out a good use case for it, I've always wondered what can I do with it, since it's supposedly a full blown Desktop PC.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721559589508/df913388-0436-406f-9a01-fea548fe9c99.png" alt class="image--center mx-auto" /></p>
<p>With the 16GB ram and an octa-core processor, android is a good option for this but regardless it's an overkill. So I installed something called <a target="_blank" href="https://fydeos.io/">FydeOS</a>.</p>
<p>FydeOS is an interesting project, it's a chromeos based project, which supports Android Apps as well as LXC containers. However, the default version of fydeOS that I have didn't seem to be stable. The Spotify app would crash the entire system. And notion felt a bit slow.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721559933385/7c360a0e-8595-45ba-8dd5-2efd21b707ab.png" alt class="image--center mx-auto" /></p>
<p>Moving on I saw that Khadas which comes with it's own Bootloader has something called as OOWOW, which is it's own bootloader and has support to install new OSes.</p>
<p>One of those is Android 13.</p>
<p>So I bit the bullet, installed and Android 13 and so far it's been flawless, I do intend to figure out how I can sort of hack around with Android.</p>
<p>Android is interesting, it's hackable and comes with ton of support for things like gamepad support, but it cannot run containers :( which is what I wanted to do. So now I'm thinking of what next is possible in this path, but I wanted a small tablet on my desk to use as a Notion/Gaming device.</p>
<p>Gaming on Android does work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721560261753/ff0baa83-4b59-4f9e-bbaa-04297ca26367.png" alt class="image--center mx-auto" /></p>
<p>The experience is quite good too. No lags or stutters here, this device can handle Genshin Impact too, I wonder if I can install Wuthering Waves etc.</p>
<p>I also tried out Google voice and it does make the device handsfree, until it can't recognize my voice, the Khadas edge 2 has a Mems microphone too.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721560392923/f7d7fd95-cc02-431d-a5b3-10b6334f008b.png" alt class="image--center mx-auto" /></p>
<p>This is it for this post, I will probably switch to linux back and see if I can get this to work somehow with a touch-friendly linux distro.</p>
]]></content:encoded></item><item><title><![CDATA[Sayonara Raspberry Pi 2b]]></title><description><![CDATA[Well like all good things come to an end, so has my journey with my Raspberry Pi 2B which has been here for almost a decade.
It's a nifty little device, and with 1 GB of ram everything was possible from running a Pi-hole DNS server to running a Pytho...]]></description><link>https://blog.mediocredevops.com/sayonara-raspberry-pi-2b</link><guid isPermaLink="true">https://blog.mediocredevops.com/sayonara-raspberry-pi-2b</guid><category><![CDATA[raspberrypi 2]]></category><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[ARM]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Wed, 03 Jul 2024 17:58:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1720029454294/00a6b1bd-1701-4161-b457-37a0d3bc6eef.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Well like all good things come to an end, so has my journey with my Raspberry Pi 2B which has been here for almost a decade.</p>
<p>It's a nifty little device, and with 1 GB of ram everything was possible from running a Pi-hole DNS server to running a Python Script to play audio back in 2016, my StackOverflow question still exists <a target="_blank" href="https://stackoverflow.com/questions/33802421/pir-sensor-with-raspberry-pi">here!</a></p>
<p>I initially got it for learning electronics but at that time the pi was quite expensive so I had to find a way to get it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720029095798/180c17e9-83c5-41d7-ae84-f99baf7f1dec.jpeg" alt class="image--center mx-auto" /></p>
<p>However, after many years, I somehow blew it up, I actually don't know how that happened, well I was too sleepy to remember but I somehow gave the <code>3v</code> GPIO pin a <code>5v</code> current while trying to get the UART to work and now my raspberry Pi is stuck in this state</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720029212729/b1397a17-417c-4667-85e8-78c313f2e87c.jpeg" alt class="image--center mx-auto" /></p>
<p>Where both the Green and the Red light are on, after reading many articles about the polyfuse blowing up and waiting several days to see if my Pi would resurrect I think it's finally time to say goodbye. Unless well I find a way to fix this somehow.</p>
<p>It's been a good buddy for about 8 years, and a small yet unknown mistake on my end caused it to blow up...</p>
<p>I've done a lot of learning on this Pi, half of which, I've never documented.</p>
<p>So long Pi2b</p>
<p>The last few random messages on my minicom terminal</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720029704865/0c176fd7-ca36-4e39-aceb-644356343c5a.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Install Ansible using pip on Risc-v]]></title><description><![CDATA[Well I've been trying to contribute to the risc-v ecosystem, and usually I get either overwhelmed by what I'm doing or I get bored... but I do work well when I've got a task on hand, like the one I took below!

I've been a fan of what Jeff Geerling d...]]></description><link>https://blog.mediocredevops.com/install-ansible-using-pip-on-risc-v</link><guid isPermaLink="true">https://blog.mediocredevops.com/install-ansible-using-pip-on-risc-v</guid><category><![CDATA[ansible]]></category><category><![CDATA[riscv]]></category><category><![CDATA[risc-v]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Tue, 02 Jul 2024 15:48:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1719935223423/b8ca4e94-3738-4483-a58f-568520a168b7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Well I've been trying to contribute to the risc-v ecosystem, and usually I get either overwhelmed by what I'm doing or I get bored... but I do work well when I've got a task on hand, like the one I took below!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1719934612397/2a013c75-3e8d-445b-a0db-2b74871b1edc.png" alt class="image--center mx-auto" /></p>
<p>I've been a fan of what Jeff Geerling does for a long time! Honestly was glad to be able to help, I even got a mention in his <a target="_blank" href="https://www.jeffgeerling.com/blog/2024/installing-ansible-on-risc-v-computer">blog post</a>!</p>
<p>So let's begin this article!</p>
<p>To go further from here, I first logged into my Vision Five 2 board.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1719934750329/d3b3be8d-86d1-4aec-b8c0-2291474be89a.png" alt class="image--center mx-auto" /></p>
<p>Then I created a Python virtual env.</p>
<pre><code class="lang-bash">python -m venv venv
python --version
</code></pre>
<p>When I initially tried <code>pip install ansible</code> after creating a virtual environment, it failed.</p>
<pre><code class="lang-bash">...
running build_ext
      running build_rust
      error: can<span class="hljs-string">'t find Rust compiler
...</span>
</code></pre>
<p>This gave me a hint, I need to install the rust compiler</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Ubuntu/Debian derivatives</span>
sudo apt install -y rustup
rustup install stable
rustc --version
</code></pre>
<p>This was all good, and I went on ahead with running the <code>pip</code> command again.</p>
<p>But that didn't work either</p>
<pre><code class="lang-bash">run pkg_config fail: Could not run `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags openssl`
        The pkg-config <span class="hljs-built_in">command</span> could not be found.

        Most likely, you need to install a pkg-config package <span class="hljs-keyword">for</span> your OS.
        Try `apt install pkg-config`, or `yum install pkg-config`,
        or `pkg install pkg-config`, or `apk add pkgconfig` depending on your distribution.

        If you<span class="hljs-string">'ve already installed it, ensure the pkg-config command is one of the
        directories in the PATH environment variable.</span>
</code></pre>
<p>So I once again, went ahead and installed <code>pkg-config</code></p>
<pre><code class="lang-bash"><span class="hljs-comment">## Ubuntu/Debian derivatives: </span>
sudo apt install -y pkg-config
<span class="hljs-comment">## Archlinux: </span>
sudo pacman -S pkg-config
</code></pre>
<p>Then finally, ansible was built! by running <code>pip install ansible</code></p>
<pre><code class="lang-bash">Building wheels <span class="hljs-keyword">for</span> collected packages: cryptography
  Building wheel <span class="hljs-keyword">for</span> cryptography (pyproject.toml) ... /
<span class="hljs-keyword">done</span>
  Created wheel <span class="hljs-keyword">for</span> cryptography: filename=cryptography-42.0.8-cp312-cp312-linux_riscv64.whl size=1497465 sha256=2effb0faf4641f1e0f958611dc3d74117c0acb07ffbef09813563e9aa406321d
  Stored <span class="hljs-keyword">in</span> directory: /home/user/.cache/pip/wheels/3d/72/97/171f6cd6eaa8c4f755fc233cbd14fe300a71acff1187ca08d5
Successfully built cryptography
Installing collected packages: resolvelib, PyYAML, pycparser, packaging, MarkupSafe, jinja2, cffi, cryptography, ansible-core, ansible
Successfully installed MarkupSafe-2.1.5 PyYAML-6.0.1 ansible-10.1.0 ansible-core-2.17.1 cffi-1.16.0 cryptography-42.0.8 jinja2-3.1.4 packaging-24.1 pycparser-2.22 resolvelib-1.0.1

[notice] A new release of pip is available: 24.0 -&gt; 24.1.1
[notice] To update, run: pip install --upgrade pip
</code></pre>
<p>It's been a while since I've written something, so hopefully this helps me get back into writing.</p>
<p>Further, I've compiled a gist for this</p>
<p><a target="_blank" href="https://gist.github.com/afro-coder/2b1f96ca31880fb66795b6dc15763e78">https://gist.github.com/afro-coder/2b1f96ca31880fb66795b6dc15763e78</a></p>
<p>Feel free to suggest edits etc.</p>
]]></content:encoded></item><item><title><![CDATA[Diving into Proxies: Connection Termination!]]></title><description><![CDATA[Hello everyone, it's been a while since I've written anything since I'm always busy. So this article will explain a simple concept that many fail to recognize and I did too.
The concept I'm talking about is called "Connection Termination", there coul...]]></description><link>https://blog.mediocredevops.com/diving-into-proxies-connection-termination</link><guid isPermaLink="true">https://blog.mediocredevops.com/diving-into-proxies-connection-termination</guid><category><![CDATA[proxies]]></category><category><![CDATA[networking]]></category><category><![CDATA[Devops]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Sat, 25 Mar 2023 13:01:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1679749160964/00a8970e-a269-419c-9617-a61ce0605c8a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone, it's been a while since I've written anything since I'm always busy. So this article will explain a simple concept that many fail to recognize and I did too.</p>
<p>The concept I'm talking about is called "Connection Termination", there could be various names for this. I recall hearing about this when I was working on writing the Developer guide for Ingress Nginx, I knew what it meant but never knew the term for it.</p>
<p>In a nutshell "Connection Termination" happens when you interact with Proxies(Even an AWS application load balancer is a reverse proxy), I know of three proxies, Envoy, Nginx, and HaProxy.</p>
<p>The image below shows you what I mean when I say connection termination(No this doesn't mean you're disconnected from the proxy)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679748236430/f2116b0c-28be-4e28-8d20-1d89aa034a28.png" alt="A diagram that shows how connection goes from your computer to the proxy and the proxy then initates a new connection to the upstream application." class="image--center mx-auto" /></p>
<p>Proxies are used to route connections to the actual applications using a single entry point. More often these are called "Reverse Proxies". When you initiate a connection to a reverse proxy your connection doesn't go directly to the application, the proxy will create a new connection to the actual service, this is one of the reasons why you'll see the Proxy IP in the application logs and not the client's actual IP.</p>
<p>This is quite useful as it allows you do to a lot of things, for example, you can add headers to the request, or maybe you want to rate-limit a request.</p>
<p>In Envoy Proxy you have something called Filter Chains these chains can be run when a request reaches the proxy, things like using an external authentication server, rate limiting, adding a wasm filter, modifying a request header, or adding headers.</p>
<p>A few things that most people ask on forums, discord, and most of the places is how do I get the actual client IP in the application logs, To be honest, this isn't needed since you can use the Proxy Logs, but sometimes you have CloudFlare in front of your application, Cloudflare is also a Reverse Proxy which connects to your application. You can instruct Cloudflare to send the IPs using the headers it provides.</p>
<p>This piece of information is really helpful when you're debugging as a single connection can be terminated at multiple places during its lifecycle. Figuring out where the termination occurs helps debug microservices.</p>
<p>A small homework from this Article is to search the headers that Cloudflare or any proxy uses to send the actual client IP.</p>
<p>Until Next time! I wish I could write more frequently but I'm bad at a lot of things including time management. I hope this helps you debug your issues faster!</p>
]]></content:encoded></item><item><title><![CDATA[Auto-Switching your Bluetooth headset using SystemD]]></title><description><![CDATA[I've been struggling with this for quite some time, but today I wanted to fix this somehow.
I use Pipewire which has a pipewire-pulse package on Archlinux that interfaces with PulseAudio applications.
However, I had to manually switch the sink to mak...]]></description><link>https://blog.mediocredevops.com/auto-switching-your-bluetooth-headset-using-systemd</link><guid isPermaLink="true">https://blog.mediocredevops.com/auto-switching-your-bluetooth-headset-using-systemd</guid><category><![CDATA[Linux]]></category><category><![CDATA[linux-basics]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Sat, 04 Jun 2022 18:00:36 GMT</pubDate><content:encoded><![CDATA[<p>I've been struggling with this for quite some time, but today I wanted to fix this somehow.</p>
<p>I use Pipewire which has a <code>pipewire-pulse</code> package on Archlinux that interfaces with PulseAudio applications.</p>
<p>However, I had to manually switch the <code>sink</code> to make my Bluetooth device the default.</p>
<p>Usually, one can do </p>
<pre><code>pactl <span class="hljs-built_in">list</span> sinks <span class="hljs-keyword">short</span>
</code></pre><p>Then </p>
<pre><code>pactl set<span class="hljs-operator">-</span>default<span class="hljs-operator">-</span>sink <span class="hljs-operator">&lt;</span>sink<span class="hljs-operator">-</span>name<span class="hljs-operator">&gt;</span>
</code></pre><p>This will set it, which is what I do via the system tray option. But I wanted an automated solution.</p>
<p>At first, I tried to use <code>udev</code> but I couldn't figure it out, but <code>SystemD</code> made it easy.</p>
<p>So I created a file under <code>/home/leon/.config/systemd/user/switch_bt.service</code> with the following content</p>
<pre><code>[Unit]
Description<span class="hljs-operator">=</span>Switch sink to the Bluetooth device
After<span class="hljs-operator">=</span>sys<span class="hljs-operator">-</span>subsystem<span class="hljs-operator">-</span>bluetooth<span class="hljs-operator">-</span>devices<span class="hljs-operator">-</span>hci0:<span class="hljs-number">256</span>.device
After<span class="hljs-operator">=</span>sys<span class="hljs-operator">-</span>devices<span class="hljs-operator">-</span>pci0000:00<span class="hljs-operator">-</span>0000:00:<span class="hljs-number">14.0</span><span class="hljs-operator">-</span>usb1<span class="hljs-number">-1</span>\x2d7<span class="hljs-number">-1</span>\x2d7:<span class="hljs-number">1.0</span><span class="hljs-operator">-</span>bluetooth<span class="hljs-operator">-</span>hci0<span class="hljs-operator">-</span>hci0:<span class="hljs-number">256</span>.device
BindsTo<span class="hljs-operator">=</span>sys<span class="hljs-operator">-</span>subsystem<span class="hljs-operator">-</span>bluetooth<span class="hljs-operator">-</span>devices<span class="hljs-operator">-</span>hci0:<span class="hljs-number">256</span>.device
BindsTo<span class="hljs-operator">=</span>sys<span class="hljs-operator">-</span>devices<span class="hljs-operator">-</span>pci0000:00<span class="hljs-operator">-</span>0000:00:<span class="hljs-number">14.0</span><span class="hljs-operator">-</span>usb1<span class="hljs-number">-1</span>\x2d7<span class="hljs-number">-1</span>\x2d7:<span class="hljs-number">1.0</span><span class="hljs-operator">-</span>bluetooth<span class="hljs-operator">-</span>hci0<span class="hljs-operator">-</span>hci0:<span class="hljs-number">256</span>.device

[Service]
ExecStartPre<span class="hljs-operator">=</span><span class="hljs-operator">/</span>bin<span class="hljs-operator">/</span>sleep <span class="hljs-number">10</span>
Type<span class="hljs-operator">=</span>oneshot
ExecStart<span class="hljs-operator">=</span><span class="hljs-operator">/</span>home<span class="hljs-operator">/</span>leon<span class="hljs-operator">/</span>.config/switch_bt.sh

[Install]
WantedBy<span class="hljs-operator">=</span>sys<span class="hljs-operator">-</span>subsystem<span class="hljs-operator">-</span>bluetooth<span class="hljs-operator">-</span>devices<span class="hljs-operator">-</span>hci0:<span class="hljs-number">256</span>.device
WantedBy<span class="hljs-operator">=</span>sys<span class="hljs-operator">-</span>devices<span class="hljs-operator">-</span>pci0000:00<span class="hljs-operator">-</span>0000:00:<span class="hljs-number">14.0</span><span class="hljs-operator">-</span>usb1<span class="hljs-number">-1</span>\x2d7<span class="hljs-number">-1</span>\x2d7:<span class="hljs-number">1.0</span><span class="hljs-operator">-</span>bluetooth<span class="hljs-operator">-</span>hci0<span class="hljs-operator">-</span>hci0:<span class="hljs-number">256</span>.device
</code></pre><p>To find the PCI device you can do <code>systemctl --all -t device</code>, you can search for the <code>hci</code>service.</p>
<p>Then I simply <code>enabled</code> the <code>systemctl --user</code> service.</p>
<pre><code>$ systemctl <span class="hljs-operator">-</span><span class="hljs-operator">-</span>user daemon<span class="hljs-operator">-</span>reload
$ systemctl <span class="hljs-operator">-</span><span class="hljs-operator">-</span>user enable switch_bt.service
$ systemctl <span class="hljs-operator">-</span><span class="hljs-operator">-</span>user switch_bt.service
</code></pre><p>The contents of <code>switch_bt.sh</code> is </p>
<pre><code><span class="hljs-meta">#!/bin/sh</span>

pactl list sinks short
pactl set-default-sink bluez_output.EB_06_EF_5E_E6_77.a2dp-sink

/usr/bin/notify-send <span class="hljs-string">'Changing Default Sink'</span> --expire-time=4000
</code></pre><p>So whenever I connect the Bluetooth device it waits for some time and then auto switches the sink to my Bluetooth device.</p>
]]></content:encoded></item><item><title><![CDATA[There is a new Entry Level Kubernetes Certificate! (KCNA) in town!]]></title><description><![CDATA[There is a new entry-level certification announced in LOS ANGELES – KubeCon + CloudNativeCon North America – October 13, 2021 for people who want to get Kubernetes certified but find Certified Kubernetes Application Developer (CKAD) too much.
Honestl...]]></description><link>https://blog.mediocredevops.com/there-is-a-new-entry-level-kubernetes-certificate-kcna-in-town</link><guid isPermaLink="true">https://blog.mediocredevops.com/there-is-a-new-entry-level-kubernetes-certificate-kcna-in-town</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[containers]]></category><category><![CDATA[conference]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Thu, 14 Oct 2021 06:50:05 GMT</pubDate><content:encoded><![CDATA[<p>There is a new entry-level certification announced in <em>LOS ANGELES – KubeCon + CloudNativeCon North America – October 13, 2021</em> for people who want to get Kubernetes certified but find Certified Kubernetes Application Developer (CKAD) too much.</p>
<p>Honestly, Kubernetes for beginners is quite exhausting, its a huge ecosystem and it takes time, I'm hoping this exam will bridge that gap.</p>
<p>So this certification is still in beta, but it will be released by the end of the year.
Unfortunately the registrations for the beta are now closed.</p>
<p>So what will the exam consist of?
From the website itself.</p>
<blockquote>
<p>KCNA will consist of a multiple-choice certification exam testing entry-level knowledge and skills in Kubernetes and the wider cloud native ecosystem. This exam is intended to demonstrate this knowledge, including how to deploy an application using basic kubectl commands, the architecture of Kubernetes (containers, pods, nodes, clusters), understanding the cloud native landscape and projects (storage, networking, GitOps, service mesh), and understanding the principles of cloud native security. </p>
</blockquote>
<p>So this means that it won't only test you on the basis of Kubernetes but it will also touch base on other technologies of the cloud-native ecosystem.</p>
<p>The breakdown of this exam is also posted</p>
<ul>
<li>Kubernetes Fundamentals (46%)<ul>
<li>Including resources, architecture, APIs, containers, and scheduling</li>
</ul>
</li>
<li>Container Orchestration (22%)<ul>
<li>Including container orchestration fundamentals, runtime, security, networking, service mesh, and storage</li>
</ul>
</li>
<li>Cloud Native Architecture (16%)<ul>
<li>Including cloud native architecture fundamentals, autoscaling, serverless, community &amp; governance, personas, and open standards</li>
</ul>
</li>
<li>Cloud Native Observability (8%)<ul>
<li>Telemetry &amp; observability, Prometheus, and cost management</li>
</ul>
</li>
<li>Cloud Native Application Delivery (8%)<ul>
<li>Application delivery fundamentals, GitOps, and CI/CD</li>
</ul>
</li>
</ul>
<p>The entire exam details can be found <a target="_blank" href="https://training.linuxfoundation.org/certification/kubernetes-cloud-native-associate/?utm_source=lftraining&amp;utm_medium=pr&amp;utm_campaign=kcna1021">here</a></p>
<p>This exam is intended to prove that you have the following knowledge</p>
<blockquote>
<p>This exam will demonstrate a candidate’s basic knowledge of Kubernetes and cloud-native technologies, including how to deploy an application using basic kubectl commands, the architecture of Kubernetes (containers, pods, nodes, clusters), understanding the cloud-native landscape and projects (storage, networking, GitOps, service mesh), and understanding the principles of cloud-native security.</p>
</blockquote>
<p>For further reading you can check out:</p>
<ul>
<li><a target="_blank" href="https://training.linuxfoundation.org/blog/entry-level-kubernetes-certification-to-help-advance-cloud-careers/">The official announcement</a></li>
<li><p><a target="_blank" href="https://training.linuxfoundation.org/certification/kubernetes-cloud-native-associate/?utm_source=lftraining&amp;utm_medium=pr&amp;utm_campaign=kcna1021">The official exam</a></p>
</li>
<li><p><a target="_blank" href="https://twitter.com/k_gamanji/status/1448325079335641091">Twitter announcement by Katie Gamanji</a></p>
</li>
</ul>
<p>I would love to discuss further about this, I'm also learning Kubernetes by watching tutorials by <a target="_blank" href="https://twitter.com/Njuchi_">Techworld with Nana</a></p>
<p>The entire playlist can be found here on <a target="_blank" href="https://www.youtube.com/watch?v=X48VuDVv0do">Youtube</a></p>
<p>I'm also on Twitter now :p in case you would like to <a target="_blank" href="https://twitter.com/mediocreDevops">follow</a></p>
<p>As always stay safe and wear a mask!</p>
]]></content:encoded></item><item><title><![CDATA[How Google Sheets and Webhooks made my life easier!]]></title><description><![CDATA[I work in Tech Support and Google Sheets helped me  automate repetitive tasks!
This helped me push messages to various teams who use Google Chats, the Webhook option present in Google Chat is amazing. 
The Goal was to track Incidents(Outages) and the...]]></description><link>https://blog.mediocredevops.com/how-google-sheets-and-webhooks-made-my-life-easier</link><guid isPermaLink="true">https://blog.mediocredevops.com/how-google-sheets-and-webhooks-made-my-life-easier</guid><category><![CDATA[Google]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[google sheets]]></category><dc:creator><![CDATA[Leon]]></dc:creator><pubDate>Wed, 13 Oct 2021 14:42:29 GMT</pubDate><content:encoded><![CDATA[<p>I work in Tech Support and Google Sheets helped me  automate repetitive tasks!</p>
<p>This helped me push messages to various teams who use <strong>Google Chats</strong>, the Webhook option present in Google Chat is amazing. </p>
<p>The Goal was to track Incidents(Outages) and then push notifications to various teams which was manual before I found out about <strong>Google Sheets Simple Triggers</strong>.</p>
<p>Here are few links that might help you get started.</p>
<p><a target="_blank" href="https://www.google.com/script/start/">How to Build Apps using Google App Script</a></p>
<p><a target="_blank" href="https://developers.google.com/apps-script/guides/triggers/">Read more about Google Sheets Triggers here</a></p>
<p><a target="_blank" href="https://developers.google.com/hangouts/chat/how-tos/webhooks">Read more about Google Chat Incoming webhooks</a></p>
<p>Now all we had to do was enter the data in a specific Cell and the <code>onEdit()</code> function would read it and post it to the necessary chat rooms.</p>
<p>You will need to add the trigger from
<a target="_blank" href="https://script.google.com">Google Scripts</a></p>
<p>Enough talk! Show me the code! </p>
<pre><code><span class="hljs-keyword">function</span> myEditNew(e) {
// The e <span class="hljs-keyword">is</span> an event <span class="hljs-keyword">Object</span>
//https://developers.google.com/apps-script/guides/triggers/events

<span class="hljs-keyword">if</span> (e.<span class="hljs-keyword">value</span>)
{
Logger.log(e.range);

Logger.log("Data: "+e.<span class="hljs-keyword">value</span>);

var val=e.<span class="hljs-keyword">value</span>;
// This <span class="hljs-keyword">function</span> <span class="hljs-keyword">is</span> <span class="hljs-keyword">to</span> <span class="hljs-keyword">get</span> the <span class="hljs-keyword">current</span> <span class="hljs-keyword">user</span> that created the task its documented <span class="hljs-keyword">in</span> the Gist at the <span class="hljs-keyword">end</span> <span class="hljs-keyword">of</span> the post
var cur_user=getCurrentUserEmail();

var <span class="hljs-type">text</span> = Utilities.formatString(<span class="hljs-string">'Incident created by *%s*: ```%s``` &lt;users/all&gt;'</span>,cur_user,val);
}

//<span class="hljs-number">1.</span> Bot Test room
// [Args[Webhook URL, Space <span class="hljs-type">Name</span>, Thread <span class="hljs-type">Name</span>]]

// <span class="hljs-keyword">To</span> <span class="hljs-keyword">get</span> the Thread ID <span class="hljs-keyword">read</span> this Stackoverflow answer

// https://webapps.stackexchange.com/questions/<span class="hljs-number">117392</span>/<span class="hljs-keyword">get</span>-link-<span class="hljs-keyword">to</span>-specific-conversation-thread-<span class="hljs-keyword">and</span>-<span class="hljs-keyword">or</span>-message-<span class="hljs-keyword">in</span>-a-chat-room-<span class="hljs-keyword">in</span>-google

var urls = [
  [
   "https://chat.googleapis.com/v1/spaces/room_id/messages?key=Webhook_ID",
   "spaces/room_id/messages/space_name.space_name",
   "spaces/Thread_ID/threads/Thread_ID"
   ],

];

// Lots <span class="hljs-keyword">of</span> Logging <span class="hljs-keyword">to</span> see <span class="hljs-keyword">if</span> Things are working properly.
Logger.log(e.range.getA1Notation());
Logger.log(e.range.getColumn());
Logger.log(val);


<span class="hljs-keyword">if</span> (e.range.getA1Notation().startsWith(<span class="hljs-string">'C'</span>) &amp;&amp; val != "")
{
// Synchronously Post it <span class="hljs-keyword">to</span> the Rooms
<span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>;i&lt;urls.length;i++)
{
var payload={
  "name":urls[i][<span class="hljs-number">1</span>],
  "thread":{
    "name":urls[i][<span class="hljs-number">2</span>]
  },
  "text":<span class="hljs-type">text</span>
};
var <span class="hljs-keyword">options</span> = {
  <span class="hljs-string">'method'</span> : <span class="hljs-string">'post'</span>,
  <span class="hljs-string">'contentType'</span>: <span class="hljs-string">'application/json'</span>,
  // Convert the JavaScript <span class="hljs-keyword">object</span> <span class="hljs-keyword">to</span> a <span class="hljs-type">JSON</span> string.
  <span class="hljs-string">'payload'</span> : <span class="hljs-type">JSON</span>.stringify(payload)
};
Logger.log(<span class="hljs-keyword">options</span>);

// UrlFetchApp Documentation
// https://developers.google.com/apps-script/reference/url-<span class="hljs-keyword">fetch</span>/url-<span class="hljs-keyword">fetch</span>-app
var response = UrlFetchApp.<span class="hljs-keyword">fetch</span>(urls[i][<span class="hljs-number">0</span>], <span class="hljs-keyword">options</span>);
Logger.log(response);

}

}
}
</code></pre><p><a target="_blank" href="https://gist.github.com/afro-coder/ebf01c3718f9be47f530168ed62fc13e">Github Gist of the entire code</a></p>
<p>Thank you for reading, if you like this article feel free to share it as always I'm open to constructive feedback and criticism, feel free to leave a comment or message me.</p>
]]></content:encoded></item></channel></rss>