<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://www.nicholasdejong.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.nicholasdejong.com/" rel="alternate" type="text/html" /><updated>2023-11-13T09:45:01+00:00</updated><id>https://www.nicholasdejong.com/feed.xml</id><title type="html">Nicholas de Jong</title><subtitle>A place on the internet about things</subtitle><entry><title type="html">Hibp-downloader - download api.pwnedpasswords.com fast</title><link href="https://www.nicholasdejong.com/hibp-downloader/" rel="alternate" type="text/html" title="Hibp-downloader - download api.pwnedpasswords.com fast" /><published>2023-11-12T00:00:00+00:00</published><updated>2023-11-12T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/hibp-downloader</id><content type="html" xml:base="https://www.nicholasdejong.com/hibp-downloader/">&lt;p&gt;&lt;strong&gt;hibp-downloader&lt;/strong&gt; is a CLI tool to efficiently download a local copy of the pwned 
password hash data from the very awesome HIBP pwned passwords api-endpoint using all 
the good bits; multiprocessing, async-processes, local-caching, content-etags and 
http2-connection pooling to make things as fast as is Pythonly possible.&lt;/p&gt;

&lt;h2 id=&quot;features&quot;&gt;Features&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Easily resume interrupted download operations into a –data-path without re-clobbering api-source.&lt;/li&gt;
  &lt;li&gt;Only download hash-prefix content blocks when the source content has changed (via content ETAG values); thus making it easy to periodically re-sync when needed.&lt;/li&gt;
  &lt;li&gt;Ability to directly query for compromised password values from the data in-place; efficient enough to attach a service with reasonable loads.&lt;/li&gt;
  &lt;li&gt;Ability to generate a single text file with in-order pwned password hash values, similar to PwnedPasswordsDownloader from the HIBP team.&lt;/li&gt;
  &lt;li&gt;Per prefix file metadata in JSON format for easy data reuse by other tooling if required.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/posts/2023-11-12/screenshot-help.png&quot; alt=&quot;screenshot-help&quot; title=&quot;screenshot-help&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;install&quot;&gt;Install&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.python.org/pypi/hibp-downloader/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/hibp-downloader.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/threatpatrols/hibp-downloader/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/pyversions/hibp-downloader.svg&quot; alt=&quot;Python Versions&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/threatpatrols/hibp-downloader/actions/workflows/build-tests.yml&quot;&gt;&lt;img src=&quot;https://github.com/threatpatrols/hibp-downloader/actions/workflows/build-tests.yml/badge.svg&quot; alt=&quot;Build Tests&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://hibp-downloader.readthedocs.io&quot;&gt;&lt;img src=&quot;https://img.shields.io/readthedocs/hibp-downloader&quot; alt=&quot;Read the Docs&quot; /&gt;&lt;/a&gt;
&lt;img src=&quot;https://img.shields.io/github/license/threatpatrols/hibp-downloader.svg&quot; alt=&quot;License&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; hibp-downloader
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Plenty more documentation and examples here -&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hibp-downloader.readthedocs.io/en/latest/&quot;&gt;hibp-downloader.readthedocs.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/threatpatrols/hibp-downloader&quot;&gt;github.com/threatpatrols/hibp-downloader&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;python-package&quot;&gt;Python Package&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.org/project/hibp-downloader/&quot;&gt;https://pypi.org/project/hibp-downloader/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">hibp-downloader is a CLI tool to efficiently download a local copy of the pwned password hash data from the very awesome HIBP pwned passwords api-endpoint using all the good bits; multiprocessing, async-processes, local-caching, content-etags and http2-connection pooling to make things as fast as is Pythonly possible.</summary></entry><entry><title type="html">Arpwitch - a modern arpwatch replacement</title><link href="https://www.nicholasdejong.com/arpwitch-a-modern-arpwatch-replacement/" rel="alternate" type="text/html" title="Arpwitch - a modern arpwatch replacement" /><published>2022-03-28T00:00:00+00:00</published><updated>2022-03-28T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/arpwitch-a-modern-arpwatch-replacement</id><content type="html" xml:base="https://www.nicholasdejong.com/arpwitch-a-modern-arpwatch-replacement/">&lt;p&gt;&lt;strong&gt;Arpwitch&lt;/strong&gt; is a modern arpwatch replacement with JSON formatted outputs and 
easy options to trigger exec commands when network changes are observed.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;outputs are JSON which makes it nice-and-easy to pair with other tools&lt;/li&gt;
  &lt;li&gt;easy triggers to &lt;strong&gt;–exec&lt;/strong&gt; system commands when new network hosts are seen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since performing an &lt;strong&gt;nmap&lt;/strong&gt; on new network hosts is a useful thing, there is also
a built-in call to nmap that will invoke nmap with relatively mild but
useful settings - you can easily fall back to a regular &lt;strong&gt;–exec&lt;/strong&gt; if you need to
do something more advanced.&lt;/p&gt;

&lt;h2 id=&quot;install&quot;&gt;Install&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.python.org/pypi/arpwitch/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/arpwitch.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/arpwitch/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/pyversions/arpwitch.svg&quot; alt=&quot;Python Versions&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/arpwitch/actions/workflows/build-tests.yml&quot;&gt;&lt;img src=&quot;https://github.com/ndejong/arpwitch/actions/workflows/build-tests.yml/badge.svg&quot; alt=&quot;Build Tests&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://arpwitch.readthedocs.io&quot;&gt;&lt;img src=&quot;https://img.shields.io/readthedocs/arpwitch&quot; alt=&quot;Read the Docs&quot; /&gt;&lt;/a&gt;
&lt;img src=&quot;https://img.shields.io/github/license/ndejong/arpwitch.svg&quot; alt=&quot;License&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; arpwitch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arpwitch &lt;span class=&quot;nt&quot;&gt;--debug&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--nmap&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--datafile&lt;/span&gt; /tmp/arpwitch.dat | jq &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The example above, watches for new network hosts; invokes an nmap scan
on them when they are discovered and saves results in XML format; saves
the arpwitch datafile to file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/arpwitch.dat&lt;/code&gt; (it’s JSON); pipes 
the output through JQ to make it look pretty.&lt;/p&gt;

&lt;p&gt;NB: arpwitch requires root/sudo access in order to packet-capture from the 
network interface(s) - the rather awesome &lt;a href=&quot;https://scapy.net/&quot;&gt;scapy&lt;/a&gt; Python 
library is used for packet capture.&lt;/p&gt;

&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Plenty more documentation and examples here -&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://arpwitch.readthedocs.io/en/latest/&quot;&gt;arpwitch.readthedocs.io/en/latest&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;p&gt;Have moved this repo from where I originally published it under verbnetworks (the laboratory)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/arpwitch&quot;&gt;github.com/ndejong/arpwitch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;python-package&quot;&gt;Python Package&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.org/project/arpwitch/&quot;&gt;pypi.org/project/arpwitch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;usage: arpwitch &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &amp;lt;datafile&amp;gt;] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &amp;lt;seconds&amp;gt;] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-req&lt;/span&gt; | &lt;span class=&quot;nt&quot;&gt;-noreq&lt;/span&gt; | &lt;span class=&quot;nt&quot;&gt;-allreq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-rep&lt;/span&gt; | &lt;span class=&quot;nt&quot;&gt;-norep&lt;/span&gt; | &lt;span class=&quot;nt&quot;&gt;-allrep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &amp;lt;&lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &amp;lt;user&amp;gt;]
                &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt; &amp;lt;address&amp;gt;] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

A modern arpwatch replacement with JSON formatted outputs and easy options to
execute commands when network changes are observed.

optional arguments:
  &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;            show this &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;message and &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-req&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--new-request&lt;/span&gt;   Select ARP request packet events that include new
                        ip/hw addresses not yet observed &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;DEFAULT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-noreq&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--no-request&lt;/span&gt;  Ignore all ARP request packet events.
  &lt;span class=&quot;nt&quot;&gt;-allreq&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--all-request&lt;/span&gt;
                        Select all ARP request packet events regardless &lt;span class=&quot;k&quot;&gt;if
                        &lt;/span&gt;addresses have been previously observed.
  &lt;span class=&quot;nt&quot;&gt;-rep&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--new-reply&lt;/span&gt;     Select only reply packet events that include new ip/hw
                        addresses not yet observed &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;DEFAULT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-norep&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--no-reply&lt;/span&gt;    Ignore all ARP reply packet events.
  &lt;span class=&quot;nt&quot;&gt;-allrep&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--all-reply&lt;/span&gt;  Select all ARP reply packet events regardless &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;the
                        addresses have been previously observed.

datafile arguments:
  &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &amp;lt;datafile&amp;gt;, &lt;span class=&quot;nt&quot;&gt;--datafile&lt;/span&gt; &amp;lt;datafile&amp;gt;
                        The arpwitch datafile where ARP event data is stored
                        as a JSON formatted file &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;REQUIRED&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; The datafile is
                        also easy to manually query and inspect with external
                        tools such as &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;jq&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &amp;lt;seconds&amp;gt;, &lt;span class=&quot;nt&quot;&gt;--interval&lt;/span&gt; &amp;lt;seconds&amp;gt;
                        Interval seconds between writing to the datafile
                        &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;DEFAULT: 30&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

ARP event &lt;span class=&quot;nb&quot;&gt;command &lt;/span&gt;execution arguments:
  The following &lt;span class=&quot;nb&quot;&gt;exec command &lt;/span&gt;substitutions are available: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;IP&lt;span class=&quot;o&quot;&gt;}=&lt;/span&gt;ipv4-address,
  &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;HW&lt;span class=&quot;o&quot;&gt;}=&lt;/span&gt;hardware-address, &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;TS&lt;span class=&quot;o&quot;&gt;}=&lt;/span&gt;timestamp-utc, &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;ts&lt;span class=&quot;o&quot;&gt;}=&lt;/span&gt;timestamp-utc-short

  &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &amp;lt;&lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--exec&lt;/span&gt; &amp;lt;&lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
                        Command line to &lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;on selected ARP events. Commands
                        are run async
  &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--nmap&lt;/span&gt;            A hard coded convenience &lt;span class=&quot;nt&quot;&gt;--exec&lt;/span&gt; that causes nmap to be
                        run against the IPv4 target with nmap-XML formatted
                        output written to the current-working-directory. This
                        option cannot be used &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;conjunction with &lt;span class=&quot;nt&quot;&gt;--exec&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &amp;lt;user&amp;gt;, &lt;span class=&quot;nt&quot;&gt;--user&lt;/span&gt; &amp;lt;user&amp;gt;
                        User to &lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;commands with, &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;not &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;this will be
                        the same user context as arpwitch.

run-mode arguments:
  Switches that invoke run-modes other than ARP capture.

  &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt; &amp;lt;address&amp;gt;, &lt;span class=&quot;nt&quot;&gt;--query&lt;/span&gt; &amp;lt;address&amp;gt;
                        Query the &amp;lt;datafile&amp;gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;an IPv4 or HW address and
                        &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;results &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;JSON formatted output and exit.
  &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;         Return the arpwitch version and exit.
  &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--witch&lt;/span&gt;           Supply one witch to &amp;lt;stdout&amp;gt; and exit.
  &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--debug&lt;/span&gt;           Debug messages to stdout.

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">Arpwitch is a modern arpwatch replacement with JSON formatted outputs and easy options to trigger exec commands when network changes are observed.</summary></entry><entry><title type="html">Azure-cli via Docker and .bash_aliases entry</title><link href="https://www.nicholasdejong.com/azure-cli-via-docker-bash-aliases/" rel="alternate" type="text/html" title="Azure-cli via Docker and .bash_aliases entry" /><published>2022-02-15T00:00:00+00:00</published><updated>2022-02-15T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/azure-cli-via-docker-bash-aliases</id><content type="html" xml:base="https://www.nicholasdejong.com/azure-cli-via-docker-bash-aliases/">&lt;p&gt;If you’re a little cautious around &lt;a href=&quot;https://krebsonsecurity.com/?s=microsoft+patch&quot;&gt;everything from Microsoft&lt;/a&gt; 
then using their Docker container is a decent approach to manage those concerns.  Unfortunately,
as tends to be the case with a lot of Microsoft &lt;a href=&quot;https://docs.microsoft.com/en-us/cli/azure/run-azure-cli-docker&quot;&gt;documentation&lt;/a&gt;,
it’s verbose and long but is somehow missing details that make things real-world useful.&lt;/p&gt;

&lt;p&gt;Fixing that then -&lt;/p&gt;

&lt;p&gt;Use the following &lt;strong&gt;.bash_aliases&lt;/strong&gt; entry to wrap the &lt;strong&gt;az&lt;/strong&gt; alias-command with something that
invokes a Docker container locally.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;az&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;docker run --rm --interactive --log-driver=none --attach stdin --attach stdout --attach stderr --volume &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/.azure:/root/.azure:rw --volume &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/.ssh:/root.ssh mcr.microsoft.com/azure-cli az&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above uses long-form docker args to make it a little easier to understand what it all 
means.&lt;/p&gt;

&lt;p&gt;Breaking that down into parts -&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;docker run&lt;/strong&gt; – causes the container from &lt;strong&gt;mcr.microsoft.com/azure-cli&lt;/strong&gt; to be run with 
the command &lt;strong&gt;az&lt;/strong&gt; (at the end of the command line)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;–rm&lt;/strong&gt; – causes the container to be removed after the command has completed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;–interactive&lt;/strong&gt; – keeps the Docker console connection open for stdin/stdout/stderr&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;–log-driver=none&lt;/strong&gt; – prevent otherwise hidden container log messages&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;–attach&lt;/strong&gt; – attach each of stdin, stdout and stderr; which is important for az since 
stderr and stdout otherwise gets collapsed onto one-another making it not-possible to pipe 
output in your local environment, such as when piping through &lt;strong&gt;jq&lt;/strong&gt; (further detail below)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;–volume ${HOME}/.azure:/root/.azure&lt;/strong&gt; – mount your ~/.azure into the Docker container 
so the Azure authentication is persistent between docker invocations; you may want to 
consider placing this mount on a separately encrypted mount.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;–volume ${HOME}/.ssh:/root.ssh&lt;/strong&gt; – mount your ~/.ssh path into the Docker container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this alias in-place you’ll be invoking a (local) Docker container to handle the “dirty” 
Microsoft stuff.&lt;/p&gt;

&lt;p&gt;Further notes:-&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;be sure to use &lt;strong&gt;–attach&lt;/strong&gt; to pass through stdin, stdout and stderr else you will have 
problems when piping output into something like &lt;strong&gt;jq&lt;/strong&gt; - the issue is that the azure-cli 
tooling writes command progress/status output to the terminal in a way that gets hidden 
by using line-feed characters - if you redirect the output from docker to file or string and 
then view that string you may miss the fact that there are line(s) not visible - if you strip
the line-feeds by piping &lt;strong&gt;| tr -d ‘\r’&lt;/strong&gt; you’ll then uncover the azure-cli status messages
at the head of string :(  that’s the long story.&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">If you’re a little cautious around everything from Microsoft then using their Docker container is a decent approach to manage those concerns. Unfortunately, as tends to be the case with a lot of Microsoft documentation, it’s verbose and long but is somehow missing details that make things real-world useful.</summary></entry><entry><title type="html">Elasticsearch Kibana CLI (eskbcli)</title><link href="https://www.nicholasdejong.com/elasticsearch-kibana-cli-release/" rel="alternate" type="text/html" title="Elasticsearch Kibana CLI (eskbcli)" /><published>2021-04-04T00:00:00+00:00</published><updated>2021-04-04T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/elasticsearch-kibana-cli-release</id><content type="html" xml:base="https://www.nicholasdejong.com/elasticsearch-kibana-cli-release/">&lt;p&gt;ElasticSearch Kibana CLI (&lt;strong&gt;eskbcli&lt;/strong&gt;) is another tool I’ve had in my back-pocket for a while 
and frequently rely on when working threat-response / threat-management cases where direct access 
to ElasticSearch is not easily possible.&lt;/p&gt;

&lt;p&gt;This situation comes up a little more often than you’d think in security-operations situations 
because the ElasticSearch backend is often tucked away and made out-of-reach (as it should be).&lt;/p&gt;

&lt;p&gt;In short - ElasticSearch Kibana CLI (&lt;strong&gt;eskbcli&lt;/strong&gt;) provides a shell interface to query an ElasticSearch
backend via the Kibana frontend.&lt;/p&gt;

&lt;p&gt;ElasticSearch Kibana CLI makes it possible to copy-paste query expressions directly from the Kibana 
user-interface and then locally access very large sets of result data.  This makes &lt;strong&gt;eskbcli&lt;/strong&gt; useful 
in SecOps situations where the ability to rapidly move from a Kibana query to raw data is valued.&lt;/p&gt;

&lt;p&gt;Configuration options are available to adjust http-headers so-as-to enable access to Kibana in 
situations that require complex user-authentication such as when Kibana is positioned behind an
OAuth reverse proxy or other session-based authentication arrangements.&lt;/p&gt;

&lt;h2 id=&quot;install&quot;&gt;Install&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.python.org/pypi/elasticsearch-kibana-cli/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/elasticsearch-kibana-cli.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/elasticsearch_kibana_cli/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/pyversions/elasticsearch-kibana-cli.svg&quot; alt=&quot;Python Versions&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/elasticsearch_kibana_cli/actions/workflows/build-tests.yml&quot;&gt;&lt;img src=&quot;https://github.com/ndejong/elasticsearch_kibana_cli/actions/workflows/build-tests.yml/badge.svg&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://elasticsearch-kibana-cli.readthedocs.io&quot;&gt;&lt;img src=&quot;https://img.shields.io/readthedocs/elasticsearch-kibana-cli&quot; alt=&quot;Read the Docs&quot; /&gt;&lt;/a&gt;
&lt;img src=&quot;https://img.shields.io/github/license/ndejong/elasticsearch_kibana_cli.svg&quot; alt=&quot;License&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; elasticsearch-kibana-cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Plenty of documentation at ReadTheDocs -&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://elasticsearch-kibana-cli.readthedocs.io&quot;&gt;elasticsearch-kibana-cli.readthedocs.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/elasticsearch_kibana_cli&quot;&gt;github.com/ndejong/elasticsearch_kibana_cli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;python-package&quot;&gt;Python Package&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.python.org/pypi/elasticsearch-kibana-cli/&quot;&gt;pypi.python.org/pypi/elasticsearch-kibana-cli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Usage: eskbcli &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;OPTIONS] COMMAND &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ARGS]...

  ElasticSearch Kibana CLI &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;eskbcli&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; provides a shell interface to query
  an ElasticSearch backend via the Kibana frontend which is useful &lt;span class=&quot;k&quot;&gt;in
  &lt;/span&gt;situations where the ElasticSearch backend is not otherwise accessible.

  ElasticSearch Kibana CLI makes it possible to copy-paste query expressions
  directly from the Kibana user-interface and &lt;span class=&quot;k&quot;&gt;then &lt;/span&gt;easily access very large
  sets of result data.  This makes the &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;eskbcli&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt; useful &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;SecOps situations
  where the ability to rapidly move from a Kibana query to raw data is
  valued.

  Configuration options are available to adjust http-headers so-as-to &lt;span class=&quot;nb&quot;&gt;enable
  &lt;/span&gt;access to Kibana &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;situations that require complex user-authentication
  such as when Kibana exists behind an OAuth reverse proxy or other session-
  based authentication arrangement.

  Documentation available https://elasticsearch-kibana-cli.readthedocs.io

Options:
  &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--config&lt;/span&gt; TEXT  Config file location&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; overrides ESKBCLI_CONFIG_FILENAME
                     environment var and the default ~/.eskbcli value.

  &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;      Verbose logging messages &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;debug level&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--quiet&lt;/span&gt;        Quiet mode, takes priority over &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;          Show the version and exit.
  &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;             Show this message and exit.

Commands:
  list     List the available eskbcli search names.
  search   Execute the named search configuration.
  show     Show the named eskbcli search configuration.
  summary  Summary report &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;search result datafile&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; use &lt;span class=&quot;s2&quot;&gt;&quot;-&quot;&lt;/span&gt; to pipe stdin.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">ElasticSearch Kibana CLI (eskbcli) is another tool I’ve had in my back-pocket for a while and frequently rely on when working threat-response / threat-management cases where direct access to ElasticSearch is not easily possible.</summary></entry><entry><title type="html">SolarEdge API interface</title><link href="https://www.nicholasdejong.com/solaredge-interface-release/" rel="alternate" type="text/html" title="SolarEdge API interface" /><published>2020-12-17T00:00:00+00:00</published><updated>2020-12-17T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/solaredge-interface-release</id><content type="html" xml:base="https://www.nicholasdejong.com/solaredge-interface-release/">&lt;p&gt;Outside the usual realm of security-things, last week I published a SolarEdge Interface, a 
command-line and a Python module interface to interact with the SolarEdge API service that’s a decent
improvement over the existing ones out there.&lt;/p&gt;

&lt;p&gt;In short -&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;All (documented) SolarEdge API endpoints are implemented with multisite support for endpoints 
that provide multisite queries.&lt;/li&gt;
  &lt;li&gt;Response data for all endpoints are available as a Python-dict structure; a Pandas-DataFrame or; 
as raw-JSON.&lt;/li&gt;
  &lt;li&gt;The command-line interface output can be formatted as a CSV; as a Pandas style JSON structure or; 
as plain-JSON.&lt;/li&gt;
  &lt;li&gt;Timestamps can be returned as datetime values with their respective site timezones applied. Doing 
so is the default behaviour, however this can be disabled if required.&lt;/li&gt;
  &lt;li&gt;Configuration via environment variables or config file is possible, thus making it safer to manage 
your API key value(s).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;install&quot;&gt;Install&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.python.org/pypi/solaredge-interface/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/solaredge-interface.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/solaredge-interface/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/pyversions/solaredge-interface.svg&quot; alt=&quot;Python Versions&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://travis-ci.org/ndejong/solaredge-interface/&quot;&gt;&lt;img src=&quot;https://api.travis-ci.org/ndejong/solaredge-interface.svg?branch=master&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://solaredge-interface.readthedocs.io&quot;&gt;&lt;img src=&quot;https://img.shields.io/readthedocs/solaredge-interface&quot; alt=&quot;Read the Docs&quot; /&gt;&lt;/a&gt;
&lt;img src=&quot;https://img.shields.io/github/license/ndejong/solaredge-interface.svg&quot; alt=&quot;License&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; solaredge-interface
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://solaredge-interface.readthedocs.io&quot;&gt;solaredge-interface.readthedocs.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Github - &lt;a href=&quot;https://github.com/ndejong/solaredge-interface&quot;&gt;github.com/ndejong/solaredge-interface&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Usage: solaredge-interface &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;OPTIONS] COMMAND &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ARGS]...

  The solaredge-interface provides a command-line interface to interact with
  the Python SolarEdgeAPI module which itself calls the SolarEdge public API
  endpoints at https://monitoringapi.solaredge.com making it even easier to
  access your data from SolarEdge.

  Configuration can be achieved through &lt;span class=&quot;nb&quot;&gt;command &lt;/span&gt;arguments, environment
  values or config file.

  Documentation available https://solaredge-interface.readthedocs.io

Options:
  &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--config&lt;/span&gt; TEXT       Override default config ~/.solaredge-interface
  &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; TEXT       Output format&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; csv, json, pandas &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;default: json&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;           Verbose logging messages &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;debug level&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--quiet&lt;/span&gt;             Quiet mode, with priority over &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-W&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--disable-warnings&lt;/span&gt;  Disable Python warnings.
  &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;               Show the version and exit.
  &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;                  Show this message and exit.

Commands:
  accounts                     Get the accessible &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;sub&amp;lt; accounts.
  site_current_power_flow      Current power flow between all elements of...
  site_data_period             Sites&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; start_date and end_date of...
  site_details                 Get site details&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; name, location, status,...
  site_energy                  Site&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; energy measurements
  site_energy_details          Detailed site energy measurements from meters
  site_environmental_benefits  Environmental benefits based on site energy...
  site_equipment_change_log    Equipment component replacements ordered by...
  site_equipment_data          Get specific inverter data &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;a given...
  site_equipment_sensors       Sensors &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the site and connections
  site_inventory               Inventory of SolarEdge equipment at the site
  site_meters                  Meter lifetime energy, metadata and...
  site_overview                Sites&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; overview data
  site_power                   Site&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; power measurements
  site_power_details           Detailed site power measurements from meters
  site_storage_data            Detailed storage information from batteries
  site_time_frame_energy       Site&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; total energy produced &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;a given...
  sites                        Get the list of accessible sites
  version_current              Current version &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &amp;lt;major.minor.revision&amp;gt;...
  version_supported            Supported version numbers &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">Outside the usual realm of security-things, last week I published a SolarEdge Interface, a command-line and a Python module interface to interact with the SolarEdge API service that’s a decent improvement over the existing ones out there.</summary></entry><entry><title type="html">Digital Multimeter interface</title><link href="https://www.nicholasdejong.com/digital-multimeter-release/" rel="alternate" type="text/html" title="Digital Multimeter interface" /><published>2020-12-03T00:00:00+00:00</published><updated>2020-12-03T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/digital-multimeter-release</id><content type="html" xml:base="https://www.nicholasdejong.com/digital-multimeter-release/">&lt;p&gt;Wrote a digital multimeter CLI tool (and Python module) to read an old Digitech QM1538 
multimeter sold by Jaycar, Australia.  This was a weekend-project that started with a 
scratchy old data-sheet that described the serial-protocol used by this thing.  I’d not 
written a serial-protocol decoder before and the tool would make my digital-multimeter 
usable via Linux and accessible remotely via SSH which is what I really wanted in this 
case.&lt;/p&gt;

&lt;p&gt;It turns out that the underlying chipset (Fortune FS9721) used by this multimeter is rather 
common among other digital multimeters too, so the CLI and accompanying Python module 
should work for a whole host of other digital multimeters out there -&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Digitech - QM1538&lt;/li&gt;
  &lt;li&gt;Digitek - DT4000ZC&lt;/li&gt;
  &lt;li&gt;PCE - PCEDM32&lt;/li&gt;
  &lt;li&gt;Tecpel - DMM8062&lt;/li&gt;
  &lt;li&gt;TekPower - TP4000ZC&lt;/li&gt;
  &lt;li&gt;UniTrend - UT30A&lt;/li&gt;
  &lt;li&gt;UniTrend - UT30E&lt;/li&gt;
  &lt;li&gt;UniTrend - UT60E&lt;/li&gt;
  &lt;li&gt;Voltcraft - VC820&lt;/li&gt;
  &lt;li&gt;Voltcraft - VC840&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Python module is written to accommodate new digital-multimeter protocols.  If you 
happen to implement another digital-multimeter protocol please do send a merge 
request - happy days.&lt;/p&gt;

&lt;h2 id=&quot;install&quot;&gt;Install&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.python.org/pypi/digital-multimeter/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/digital-multimeter.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/digital-multimeter/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/pyversions/digital-multimeter.svg&quot; alt=&quot;Python Versions&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://digital-multimeter.readthedocs.io&quot;&gt;&lt;img src=&quot;https://img.shields.io/readthedocs/digital-multimeter&quot; alt=&quot;Read the Docs&quot; /&gt;&lt;/a&gt;
&lt;img src=&quot;https://img.shields.io/github/license/ndejong/digital-multimeter.svg&quot; alt=&quot;License&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; digital-multimeter
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://digital-multimeter.readthedocs.io&quot;&gt;digital-multimeter.readthedocs.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/digital-multimeter&quot;&gt;github.com/ndejong/digital-multimeter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Usage: dmm &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;OPTIONS] COMMAND &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ARGS]...

  Digital multimeter CLI tool utilizing the Python3 DigitalMultimeter module.

  Configuration can be achieved through &lt;span class=&quot;nb&quot;&gt;command &lt;/span&gt;arguments, environment values
  or config file.

  Documentation available https://digital-multimeter.readthedocs.io

Options:
  &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--quiet&lt;/span&gt;             Quiet mode&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; priority over &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;           Verbose logging&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; debug level.
  &lt;span class=&quot;nt&quot;&gt;-W&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--disable-warnings&lt;/span&gt;  Disable Python warnings.
  &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;               Show the version and exit.
  &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;                  Show this message and exit.

Commands:
  models  Provides a list of the supported digital multimeter models
  &lt;span class=&quot;nb&quot;&gt;read    &lt;/span&gt;Read the digital multimeter and output data &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;various formats
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">Wrote a digital multimeter CLI tool (and Python module) to read an old Digitech QM1538 multimeter sold by Jaycar, Australia. This was a weekend-project that started with a scratchy old data-sheet that described the serial-protocol used by this thing. I’d not written a serial-protocol decoder before and the tool would make my digital-multimeter usable via Linux and accessible remotely via SSH which is what I really wanted in this case.</summary></entry><entry><title type="html">Env-Alias environment helper utility</title><link href="https://www.nicholasdejong.com/env-alias-release/" rel="alternate" type="text/html" title="Env-Alias environment helper utility" /><published>2020-03-01T00:00:00+00:00</published><updated>2020-03-01T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/env-alias-release</id><content type="html" xml:base="https://www.nicholasdejong.com/env-alias-release/">&lt;p&gt;Env-Alias is a helper utility to create shell alias commands that easily set collections of 
environment variables often with secret values from a variety of data-sources and data-formats.&lt;/p&gt;

&lt;p&gt;Typically this tool is invoked via an entry in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bash_aliases&lt;/code&gt; with an entry in the form&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;env-alias my-alias-name ~/path-to/my-alias-name-config-file.yml&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Where this example would establish a shell alias command for the alias &lt;strong&gt;my-alias-name&lt;/strong&gt; that 
then invokes the env-alias-generator with configuration from &lt;strong&gt;~/path-to/my-alias-name-config-file.yml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That all might sound quirky, however the mechanism is enormously useful in working with large sets of 
environment variables from encrypted or otherwise secured data-sources which means an environment 
configuration can be easily committed to source control without the secret values.&lt;/p&gt;

&lt;h2 id=&quot;features&quot;&gt;Features&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Data sources: local-file, http-remote, exec-stdout or directly-set&lt;/li&gt;
  &lt;li&gt;Source file formats: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;text&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ini&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yaml&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Select using jq-style selectors, xpath selectors or line-numbers&lt;/li&gt;
  &lt;li&gt;Reference other env values within configuration&lt;/li&gt;
  &lt;li&gt;Content-Type detection for http-remote data-sources to automatically assign appropriate parser&lt;/li&gt;
  &lt;li&gt;Run exec helper commands without content assignment for creating setups&lt;/li&gt;
  &lt;li&gt;Logs output to STDERR&lt;/li&gt;
  &lt;li&gt;Easy installation using PyPI &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Plenty of documentation and examples - &lt;a href=&quot;https://env-alias.readthedocs.io&quot;&gt;https://env-alias.readthedocs.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;install&quot;&gt;Install&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.python.org/pypi/env-alias/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/env-alias.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/env-alias/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/pyversions/env-alias.svg&quot; alt=&quot;Python Versions&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://github.com/ndejong/env-alias/actions/workflows/build-tests.yml&quot;&gt;&lt;img src=&quot;https://github.com/ndejong/env-alias/actions/workflows/build-tests.yml/badge.svg&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://env-alias.readthedocs.io&quot;&gt;&lt;img src=&quot;https://img.shields.io/readthedocs/env-alias&quot; alt=&quot;Read the Docs&quot; /&gt;&lt;/a&gt;
&lt;img src=&quot;https://img.shields.io/github/license/ndejong/env-alias.svg&quot; alt=&quot;License&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--upgrade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; env-alias
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Read the documentation, there really is a lot of awesome things to do with env-alias&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://env-alias.readthedocs.io&quot;&gt;env-alias.readthedocs.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/env-alias&quot;&gt;github.com/ndejong/env-alias&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">Env-Alias is a helper utility to create shell alias commands that easily set collections of environment variables often with secret values from a variety of data-sources and data-formats.</summary></entry><entry><title type="html">Python client for pfSense FauxAPI</title><link href="https://www.nicholasdejong.com/python-client-for-pfsense-fauxapi/" rel="alternate" type="text/html" title="Python client for pfSense FauxAPI" /><published>2019-03-17T00:00:00+00:00</published><updated>2019-03-17T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/python-client-for-pfsense-fauxapi</id><content type="html" xml:base="https://www.nicholasdejong.com/python-client-for-pfsense-fauxapi/">&lt;p&gt;For longest time I’d been meaning to roll a PyPi package for the Python client interface to FauxAPI, and it is now a
thing - it also closes the long open issue &lt;a href=&quot;https://github.com/ndejong/pfsense_fauxapi/issues/22&quot;&gt;#22&lt;/a&gt; asking about PyPi from way back.&lt;/p&gt;

&lt;h3 id=&quot;pfsense-fauxapi&quot;&gt;pfsense-fauxapi&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://pypi.org/project/pfsense-fauxapi/&quot;&gt;&lt;img src=&quot;https://img.shields.io/pypi/v/pfsense-fauxapi.svg&quot; alt=&quot;PyPi&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://travis-ci.org/ndejong/pfsense_fauxapi_client_python&quot;&gt;&lt;img src=&quot;https://travis-ci.org/ndejong/pfsense_fauxapi_client_python.svg?branch=master&quot; alt=&quot;Build Status&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install it using pip:-&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;pfsense-fauxapi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;github-project&quot;&gt;Github project&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/pfsense_fauxapi_client_python&quot;&gt;github.com/ndejong/pfsense_fauxapi_client_python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;command-line&quot;&gt;Command Line&lt;/h3&gt;
&lt;p&gt;Additionally this pip-package provides a command-line interface to work with FauxAPI&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;usage: fauxapi &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;host]] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--apikey&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;key]] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--apisecret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;secret]]
               &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--verified-ssl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; ...] &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;

FauxAPI

optional arguments:
  &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;            show this &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;message and &lt;span class=&quot;nb&quot;&gt;exit

&lt;/span&gt;Call:
  &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;host]         Host address of the target pfSense host with the
                        PfsenseFauxapi package installed.
  &lt;span class=&quot;nt&quot;&gt;--apikey&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;key]        FauxAPI apikey value - alternatively via the
                        FAUXAPI_APIKEY environment variable.
  &lt;span class=&quot;nt&quot;&gt;--apisecret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;secret]  FauxAPI apisecret value - alternatively via the
                        FAUXAPI_APIKEY environment variable.
  &lt;span class=&quot;nt&quot;&gt;--verified-ssl&lt;/span&gt;        Enable SSL certificate checks - default does NOT check
                        SSL certificates.
  &lt;span class=&quot;nt&quot;&gt;--debug&lt;/span&gt;               Enable debug response from the remote FauxAPI -
                        helpful &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;tracking down issues.
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;            The FauxAPI &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;being called
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;       Arguments to the &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;, space separated
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Command line example, using environment variables to pass the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FAUXAPI_APIKEY&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FAUXAPI_APIKEY&lt;/code&gt; credentials.&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;fauxapi &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt; 192.168.1.200 gateway_status | jq &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;callid&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;5c8d0f7361cba&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;action&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;gateway_status&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;ok&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;gateway_status&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;10.11.12.1&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;monitorip&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.10.10.1&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;srcip&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;10.10.10.200&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;WAN_DHCP&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;delay&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;0.422ms&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;stddev&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;0.073ms&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;loss&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;0.0%&quot;&lt;/span&gt;,
        &lt;span class=&quot;s2&quot;&gt;&quot;status&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;none&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;package-testing&quot;&gt;Package Testing&lt;/h3&gt;
&lt;p&gt;Tests for (almost) all client-side function calls are implemented with mocked API response data
you can check them with pytest&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  python setup.py &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Packages are tested via Travis
&lt;a href=&quot;https://travis-ci.org/ndejong/pfsense_fauxapi_client_python&quot;&gt;travis-ci.org/ndejong/pfsense_fauxapi_client_python&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;package-build&quot;&gt;Package Build&lt;/h3&gt;
&lt;p&gt;Should you need/want to build the package from source&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# obtain the source material&lt;/span&gt;
git clone https://github.com/ndejong/pfsense_fauxapi_client_python.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;pfsense_fauxapi_client_python

&lt;span class=&quot;c&quot;&gt;# build the package&lt;/span&gt;
python setup.py sdist bdist_wheel

&lt;span class=&quot;c&quot;&gt;# install the package from the .whl file in the dist path &lt;/span&gt;
pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;dist/pfsense&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.whl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">For longest time I’d been meaning to roll a PyPi package for the Python client interface to FauxAPI, and it is now a thing - it also closes the long open issue #22 asking about PyPi from way back.</summary></entry><entry><title type="html">Terraform + Digital Ocean Droplets</title><link href="https://www.nicholasdejong.com/terraform-digitalocean-droplet/" rel="alternate" type="text/html" title="Terraform + Digital Ocean Droplets" /><published>2019-02-20T00:00:00+00:00</published><updated>2019-02-20T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/terraform-digitalocean-droplet</id><content type="html" xml:base="https://www.nicholasdejong.com/terraform-digitalocean-droplet/">&lt;p&gt;This Terraform module creates a Digital Ocean Droplet using Terraform with desirable 
additional features.  The module is essentially a wrapper around the Digital Ocean 
provider using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cloudinit&lt;/code&gt; script to provide additional features:-&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;remount existing volumes&lt;/li&gt;
  &lt;li&gt;create an initial user with an sshkey&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;update&quot;&gt;Update&lt;/h3&gt;
&lt;p&gt;2022-03-28 - the source for this module has been migrated from github &lt;strong&gt;verbnetworks&lt;/strong&gt; to
github &lt;strong&gt;ndejong&lt;/strong&gt; - the module at &lt;strong&gt;registry.terraform.io&lt;/strong&gt; points to verbnetworks which is
redirected to ndejong - yeeeee.&lt;/p&gt;

&lt;p&gt;Current version is now v0.2.1&lt;/p&gt;

&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/terraform-digitalocean-droplet&quot;&gt;github.com/ndejong/terraform-digitalocean-droplet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;terraform-module&quot;&gt;Terraform Module&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://registry.terraform.io/modules/verbnetworks/droplet/digitalocean&quot;&gt;registry.terraform.io/modules/ndejong/droplet/digitalocean&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">This Terraform module creates a Digital Ocean Droplet using Terraform with desirable additional features. The module is essentially a wrapper around the Digital Ocean provider using a cloudinit script to provide additional features:- remount existing volumes create an initial user with an sshkey</summary></entry><entry><title type="html">Keybase.io Network Graphs</title><link href="https://www.nicholasdejong.com/keybase-network-graph/" rel="alternate" type="text/html" title="Keybase.io Network Graphs" /><published>2019-01-06T00:00:00+00:00</published><updated>2019-01-06T00:00:00+00:00</updated><id>https://www.nicholasdejong.com/keybase-network-graph</id><content type="html" xml:base="https://www.nicholasdejong.com/keybase-network-graph/">&lt;p&gt;Recently I became interested in &lt;a href=&quot;https://keybase.io&quot;&gt;Keybase.io&lt;/a&gt; and really wanted to be able explore my network-graph 
using &lt;a href=&quot;https://gephi.org/&quot;&gt;Gephi&lt;/a&gt;, so I wrote a quick tool to collect the data from Keybase; dump it into GraphML file;
then loaded it up in Gephi.  The results nicely highlight who-knows-who; the strengths and weaknesses in my own Keybase
network; and super connector users with many followers.&lt;/p&gt;

&lt;h3 id=&quot;keybase&quot;&gt;Keybase&lt;/h3&gt;
&lt;p&gt;Keybase is an interesting project, and the circle-of-trust improvements their tooling provides is probably better than
anything else out there at the moment.  The obvious concern is whether they have a business model that provides 
sufficient value to people (or enterprises) that will make Keybase long-term viable.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://keybase.io/blog/2015-07-15/keybase-raises-series-a&quot;&gt;Keybase raises $10.8M&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.crunchbase.com/organization/keybase&quot;&gt;Keybase on Crunchbase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;github-project&quot;&gt;Github project&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ndejong/keybase-network-graph&quot;&gt;https://github.com/ndejong/keybase-network-graph&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;command-line&quot;&gt;Command line&lt;/h3&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./keybase-network-graph.py &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;
usage: keybase-network-graph.py &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--uid&lt;/span&gt; &amp;lt;uid&amp;gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--depth&lt;/span&gt; &amp;lt;depth&amp;gt;]
                                &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--path&lt;/span&gt; &amp;lt;path&amp;gt;] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--nograph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
Keybase Network Grapher

optional arguments:
  &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt;, &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;       show this &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;message and &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--uid&lt;/span&gt; &amp;lt;uid&amp;gt;      Initial uid to start collecting data on, required.
  &lt;span class=&quot;nt&quot;&gt;--depth&lt;/span&gt; &amp;lt;depth&amp;gt;  Maximum depth of user connections to collect data on,
                   default &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1
  &lt;span class=&quot;nt&quot;&gt;--path&lt;/span&gt; &amp;lt;path&amp;gt;    Maximum depth of user connections to collect data down to,
                   default &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /tmp/keybase-network-graph
  &lt;span class=&quot;nt&quot;&gt;--nograph&lt;/span&gt;        Prevent GraphML generation.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;visualizations-in-gephi&quot;&gt;Visualizations in Gephi&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/ndejong/keybase-network-graph/master/assets/screenshot_101043.png&quot; alt=&quot;screenshot_101043.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/ndejong/keybase-network-graph/master/assets/screenshot_075321.png&quot; alt=&quot;screenshot_075321.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/ndejong/keybase-network-graph/master/assets/screenshot_074349.png&quot; alt=&quot;screenshot_074349.png&quot; /&gt;&lt;/p&gt;</content><author><name>Nicholas de Jong</name></author><summary type="html">Recently I became interested in Keybase.io and really wanted to be able explore my network-graph using Gephi, so I wrote a quick tool to collect the data from Keybase; dump it into GraphML file; then loaded it up in Gephi. The results nicely highlight who-knows-who; the strengths and weaknesses in my own Keybase network; and super connector users with many followers.</summary></entry></feed>