<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Cumulocity CLI Blog</title>
        <link>https://reubenmiller.github.io/demos/</link>
        <description>Cumulocity CLI Blog</description>
        <lastBuildDate>Wed, 06 Sep 2023 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[go-c8y-cli update - Sept 2023]]></title>
            <link>https://reubenmiller.github.io/demos/2023-09-update/</link>
            <guid>https://reubenmiller.github.io/demos/2023-09-update/</guid>
            <pubDate>Wed, 06 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Update on what's new with go-c8y-cli and showing real life scenarios]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://reubenmiller.github.io/demos/2023-09-update/#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>Welcome to an update on go-c8y-cli. For those who are new to the scene, go-c8y-cli is a cli tool used to interact with the powerful and very stable Cumulocity API. It is developed to make you as productive as possible so that you can get the most out of your IoT Platform with minimal effort whilst protecting you against stupid mistakes.</p>
<p>Development of it started a few years ago when I was working for a company which used the Cumulocity platform. I quickly ran into limitations with the defacto PostMan and also wanted a solution which enabled me to quickly explore/fix/create items in Cumulocity and be able to re-use the same commands in a script to automate a process. I made it open source as I found that if it can make my life easier, then other people should also be able to benefit, and it grew from there.</p>
<p>Now we have an open source tool which is adaptable to many use-cases and tries to encourage best practices, whilst be super composable so it can be used for both basic and more complex scenarios.</p>
<p>As you might guess, it is developed in golang and it is a single compiled binary available on a large cross section of platforms.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-use-cases">Common use-cases<a href="https://reubenmiller.github.io/demos/2023-09-update/#common-use-cases" class="hash-link" aria-label="Direct link to Common use-cases" title="Direct link to Common use-cases" translate="no">​</a></h2>
<p>Below show some of the common use-cases built from a combination of some of my daily tasks, and some feedback from <a href="https://github.com/reubenmiller/go-c8y-cli/discussions/298" target="_blank" rel="noopener noreferrer" class="">real users</a>:</p>
<ul>
<li class="">Tenant setup (create tenants, add users, configure retention rules)</li>
<li class="">API discovery</li>
<li class="">Troubleshooting - Something went wrong, but when/how/why?</li>
<li class="">Simulation / Rapid Prototyping</li>
<li class="">CI/CD - deployment, cleanup<!-- -->
<ul>
<li class="">Upload and activate web applications and microservices</li>
<li class="">Remove device certificates</li>
<li class="">Delete devices after tests have run</li>
</ul>
</li>
<li class="">Reporting</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-new">What's New<a href="https://reubenmiller.github.io/demos/2023-09-update/#whats-new" class="hash-link" aria-label="Direct link to What's New" title="Direct link to What's New" translate="no">​</a></h2>
<p>go-c8y-cli is constantly being improved and new features are added frequently. Some of the goodies that have been developed over the last year include:</p>
<ul>
<li class="">Support for Extensions - easier to create/share/install extensions</li>
<li class="">Progress bars for binary uploads and downloads</li>
<li class="">Support for notifications2 API</li>
<li class="">Output templates - shape the output of your data using Jsonnet templates</li>
<li class="">Additional template (jsonnet) functions (e.g. for date manipulation, get/select properties using dot notation)</li>
<li class="">csv utilities</li>
<li class="">DataHub API</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="https://reubenmiller.github.io/demos/2023-09-update/#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no">​</a></h2>
<p>As always a tool is useless unless it can be installed on your system.</p>
<ul>
<li class=""><a href="https://c8y.app/docs/installation/shell-installation/" target="_blank" rel="noopener noreferrer" class="">shell</a></li>
<li class=""><a href="https://c8y.app/docs/installation/docker-installation/" target="_blank" rel="noopener noreferrer" class="">Docker</a></li>
<li class=""><a href="https://c8y.app/docs/installation/powershell-installation/" target="_blank" rel="noopener noreferrer" class="">PowerShell</a></li>
</ul>
<p>Or you can always download the binary directly using some new instructions (which will eventually also make it on the website as well)</p>
<ul>
<li class=""><a href="https://gist.github.com/reubenmiller/72d317cd2b0dcce67e0300e86713181e" target="_blank" rel="noopener noreferrer" class="">Manually installing go-c8y-cli</a></li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-misconceptions">Common misconceptions<a href="https://reubenmiller.github.io/demos/2023-09-update/#common-misconceptions" class="hash-link" aria-label="Direct link to Common misconceptions" title="Direct link to Common misconceptions" translate="no">​</a></h3>
<p>Just to clarify a few common misconceptions which I've heard in the last year or two:</p>
<ul>
<li class="">It relies on PowerShell...No, this has not been the case since June 2021!</li>
<li class="">This is just postman on the command line right?...nope, it does so much more!</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="basics">Basics<a href="https://reubenmiller.github.io/demos/2023-09-update/#basics" class="hash-link" aria-label="Direct link to Basics" title="Direct link to Basics" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="getting-around">Getting around<a href="https://reubenmiller.github.io/demos/2023-09-update/#getting-around" class="hash-link" aria-label="Direct link to Getting around" title="Direct link to Getting around" translate="no">​</a></h3>
<p>Now for the demo part, the following items will be quickly shown so that it will help you navigate go-c8y-cli and understand the basic principles.</p>
<ul>
<li class="">Creating / activating a session<!-- -->
<ul>
<li class="">Caveats: SSO users are not supported due to a platform limitation (though this may change in the future)</li>
<li class="">Protecting against dumb mistakes</li>
</ul>
</li>
<li class="">Using command completion</li>
<li class="">Help and examples</li>
<li class="">Viewing data and output formats</li>
<li class="">Piping between commands</li>
<li class="">Template generation</li>
<li class="">Online documentation</li>
</ul>
<hr>
<h1>Use-cases</h1>
<p>This section shows some examples of real world use-cases which I have personally needed at some point in time, or other people have are using in their Cumulocity journey.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="exploring-your-data">Exploring your data<a href="https://reubenmiller.github.io/demos/2023-09-update/#exploring-your-data" class="hash-link" aria-label="Direct link to Exploring your data" title="Direct link to Exploring your data" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-caution admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_BuS1"><p>Always consider how many devices you have in your platform, don't blindly run commands on &gt;=10K devices without thinking about the consequences!!!</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="list-of-device-types-used-in-the-platform">List of device types used in the platform<a href="https://reubenmiller.github.io/demos/2023-09-update/#list-of-device-types-used-in-the-platform" class="hash-link" aria-label="Direct link to List of device types used in the platform" title="Direct link to List of device types used in the platform" translate="no">​</a></h3>
<p>Sometimes it is helpful to view get an overview of the different device types in your tenant. The go-c8y-cli can be easily combined with other commands to extract the information that you need:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y devices list </span><span class="token parameter variable" style="color:#36acaa">--includeAll</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--select</span><span class="token plain"> </span><span class="token builtin class-name">type</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> csv </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sort</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">uniq</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sort</span><span class="token plain"> --human-numeric-sort</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cleaning-up-devices">Cleaning up devices<a href="https://reubenmiller.github.io/demos/2023-09-update/#cleaning-up-devices" class="hash-link" aria-label="Direct link to Cleaning up devices" title="Direct link to Cleaning up devices" translate="no">​</a></h3>
<p>Use case: The dev team is prototyping a lot and slowly there are more and more devices in the platform which are no longer being used.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y devices list </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token plain"> Linux </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y devices delete </span><span class="token parameter variable" style="color:#36acaa">-f</span><br></span></code></pre></div></div>
<p>You can also run use multiple workers to process the input which will make the overall job quicker, however you should always do this in moderation, as you don't want to put unnecessary load on the platform for an admin task.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y devices list </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token plain"> nx_Microservice </span><span class="token parameter variable" style="color:#36acaa">--creationTimeDateTo</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-60d</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--pageSize</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y devices delete </span><span class="token parameter variable" style="color:#36acaa">--progress</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--workers</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--delay</span><span class="token plain"> 1000ms</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="exploring-the-api">Exploring the api<a href="https://reubenmiller.github.io/demos/2023-09-update/#exploring-the-api" class="hash-link" aria-label="Direct link to Exploring the api" title="Direct link to Exploring the api" translate="no">​</a></h2>
<p>go-c8y-cli is also a great tool for API discovery, and also converting the commands to actual HTTP requests which can be ported to other languages, e.g. Python. There is a bit of overlap with the <a href="https://cumulocity.com/api/core/" target="_blank" rel="noopener noreferrer" class="">interactive OpenAPI spec</a>, however go-c8y-cli tries to put all of the commands in the context of the user, rather than a pure API view. For example <code>c8y devices list</code> is just doing a managed object query with a specific filter on top, and there is no specific "device" endpoint.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-commands-to-view-the-query-in-your-expected-context">Use commands to view the query in your expected context<a href="https://reubenmiller.github.io/demos/2023-09-update/#use-commands-to-view-the-query-in-your-expected-context" class="hash-link" aria-label="Direct link to Use commands to view the query in your expected context" title="Direct link to Use commands to view the query in your expected context" translate="no">​</a></h3>
<p>You can inspect what the actual HTTP call looks like without sending it to Cumulocity. This helps you better understand the structure of the API, and you can also port the HTTP request to what ever language you want, and you have the exact call that you need.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y devices list </span><span class="token parameter variable" style="color:#36acaa">--name</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"tedge_*"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--creationTimeDateFrom</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-10d</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--dry</span><br></span></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">What If: Sending [GET] request to [https://test-ci-runner01.latest.stage.c8y.io/inventory/managedObjects?q=%24filter%3D%28name+eq+%27testme%27%29+and+%28creationTime.date+ge+%272023-08-27T10%3A16%3A05.06709%2B10%3A00%27%29+%24orderby%3Dname]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">### GET /inventory/managedObjects?q=$filter=(name eq 'testme') and (creationTime.date ge '2023-08-27T10:16:05.06709+10:00') $orderby=name</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">| header            | value</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|-------------------|---------------------------</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">| Accept            | application/json</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">| Authorization     | Bearer {token}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="troubleshooting">Troubleshooting<a href="https://reubenmiller.github.io/demos/2023-09-update/#troubleshooting" class="hash-link" aria-label="Direct link to Troubleshooting" title="Direct link to Troubleshooting" translate="no">​</a></h2>
<p>Troubleshooting is a common task throughout your IoT journey. It can range from a root cause analysis to respond to a production event, or simply checking which devices don't conform to the expected data schema.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="check-which-devices-dont-have-an-external-identity">Check which devices don't have an external identity<a href="https://reubenmiller.github.io/demos/2023-09-update/#check-which-devices-dont-have-an-external-identity" class="hash-link" aria-label="Direct link to Check which devices don't have an external identity" title="Direct link to Check which devices don't have an external identity" translate="no">​</a></h3>
<p>In a perfect world, every device will have an external identity (which makes it easier and quicker to reference). However during development it is fairly easy to forget things, or there is a bug which causes the creation of the external identity to fail.</p>
<p>The following one-liner shows how to check which devices</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y devices list </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y identity list </span><span class="token parameter variable" style="color:#36acaa">--outputTemplate</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"if std.length(output) == 0 then input.value else ''"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--select</span><span class="token plain"> id,name,type,self </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> json</span><br></span></code></pre></div></div>
<p>Though it is always good to narrow down your search space first before doing this as checking the identity requires one request per device, so in reality you probably want to filter the devices first, and then check if the identity exists or not:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y devices list </span><span class="token parameter variable" style="color:#36acaa">--query</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"has(myFragment) and name eq 'test*'"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y identity list </span><span class="token parameter variable" style="color:#36acaa">--outputTemplate</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"if std.length(output) == 0 then input.value else ''"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--select</span><span class="token plain"> id,name,type,self </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> json</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="viewing-the-inventory-data-structure">Viewing the inventory data structure<a href="https://reubenmiller.github.io/demos/2023-09-update/#viewing-the-inventory-data-structure" class="hash-link" aria-label="Direct link to Viewing the inventory data structure" title="Direct link to Viewing the inventory data structure" translate="no">​</a></h3>
<p>Being able to inspect the managed object information (e.g. devices, agents etc.) can be really useful to spot why something isn't working or just to spot inconsistencies across devices (which happens when you're working in larger team).</p>
<p>You can inspect single items and pretty print it using some of the default aliases (to reduce the amount of typing for common tasks):</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y mo </span><span class="token number" style="color:#36acaa">43903</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="downloading-multiple-binaries-files-from-the-platform">Downloading multiple binaries files from the platform<a href="https://reubenmiller.github.io/demos/2023-09-update/#downloading-multiple-binaries-files-from-the-platform" class="hash-link" aria-label="Direct link to Downloading multiple binaries files from the platform" title="Direct link to Downloading multiple binaries files from the platform" translate="no">​</a></h3>
<p>The larger your fleet of devices, the harder it can to do some root cause analysis on them. Using the power of pipelines it makes a manual task such as downloading event binaries (aka attachments) a simple one-liner:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y events list </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token plain"> c8y-configuration-plugin </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y events downloadBinary </span><span class="token parameter variable" style="color:#36acaa">--noProgress</span><br></span></code></pre></div></div>
<p>Or using the power of output templates, you can even add combine information in the request with the output:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y events list </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token plain"> c8y-configuration-plugin </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y events downloadBinary </span><span class="token parameter variable" style="color:#36acaa">--noProgress</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--outputTemplate</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"'</span><span class="token string entity" style="color:#36acaa">\n</span><span class="token string entity" style="color:#36acaa">\n</span><span class="token string" style="color:#e3116c"># Device: ' + request.url + '</span><span class="token string entity" style="color:#36acaa">\n</span><span class="token string" style="color:#e3116c">' + output + '</span><span class="token string entity" style="color:#36acaa">\n</span><span class="token string" style="color:#e3116c">'"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sed</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'s|\\n|\n|g'</span><br></span></code></pre></div></div>
<p><strong>Saving the files to disk</strong></p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">c8y events list </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token plain"> c8y-configuration-plugin </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y events downloadBinary </span><span class="token parameter variable" style="color:#36acaa">--noProgress</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--outputFileRaw</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"{filename}.txt"</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="download-device-logs">Download device logs<a href="https://reubenmiller.github.io/demos/2023-09-update/#download-device-logs" class="hash-link" aria-label="Direct link to Download device logs" title="Direct link to Download device logs" translate="no">​</a></h3>
<p>This is a more advanced example but it is meant to just show how useful the pipeline is to chain multiple commands together to build a complex workflow.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">301</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y bulkoperations listOperations </span><span class="token parameter variable" style="color:#36acaa">--status</span><span class="token plain"> FAILED </span><span class="token parameter variable" style="color:#36acaa">--includeAll</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y operations create </span><span class="token parameter variable" style="color:#36acaa">--template</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"{c8y_LogfileRequest:{logFile:'software-management',dateFrom: _.Date(input.value.creationTime, '-120min'), dateTo: _.Date('now'), maximumLines:1000,searchText:''}}"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--description</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Collect logs"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y operations </span><span class="token function" style="color:#d73a49">wait</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--status</span><span class="token plain"> SUCCESSFUL </span><span class="token parameter variable" style="color:#36acaa">--select</span><span class="token plain"> c8y_LogfileRequest.file </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> csv </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> c8y api</span><br></span></code></pre></div></div>
<p>The above command is doing the following:</p>
<ol>
<li class="">Get a list of all of operations which failed related to a specific bulk operation</li>
<li class="">Create an operation on the device where the operation failed to collect a specific log file using a time filter 2 hours before the creation of the operation until now.</li>
<li class="">Wait until the log file request operation is finished, then pipe the link to the file</li>
<li class="">Download the file (using the generic <code>c8y api</code> command)</li>
</ol>
<p>This allows you to write all of the information to a file where you can use grep to see what was happening</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cicd">CI/CD<a href="https://reubenmiller.github.io/demos/2023-09-update/#cicd" class="hash-link" aria-label="Direct link to CI/CD" title="Direct link to CI/CD" translate="no">​</a></h2>
<p>A new GitHub Actions called <a href="https://github.com/reubenmiller/setup-go-c8y-cli" target="_blank" rel="noopener noreferrer" class="">setup-go-c8y-cli</a> has been added to make it even easier to install go-c8y-cli in your workflow.</p>
<p>Check out the <a href="https://github.com/reubenmiller/go-c8y-cli-demos/blob/demo-2023-09-07/.github/workflows/deploy-example02.yml" target="_blank" rel="noopener noreferrer" class="">example workflow</a> for some examples of what is possible.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploying-applications">Deploying applications<a href="https://reubenmiller.github.io/demos/2023-09-update/#deploying-applications" class="hash-link" aria-label="Direct link to Deploying applications" title="Direct link to Deploying applications" translate="no">​</a></h3>
<p>Deploying microservices and web applications are simple one-liners which are able to deploy new versions of your applications directly in your workflow.</p>
<p>go-c8y-cli can also be used to clean up old versions of web applications so that your platform makes the most efficient use of resources.</p>
<ol>
<li class="">Deploy a microservices</li>
<li class="">Deploy a web application</li>
<li class="">Delete older versions of the web application only keeping the last X versions</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="device-management">Device Management<a href="https://reubenmiller.github.io/demos/2023-09-update/#device-management" class="hash-link" aria-label="Direct link to Device Management" title="Direct link to Device Management" translate="no">​</a></h3>
<p>go-c8y-cli is not just limited to deploying applications, but you can also use as part of a GitOps style device manager which looks at deploying software updates to devices.</p>
<p>The device management part of the workflow involves</p>
<ol>
<li class="">Create/Upload a new configuration binary to the Configuration Repository</li>
<li class="">Create/Upload a new version of software to the Software Repository</li>
<li class="">Install software on a small group of devices (e.g. Canary group) via a Bulk Operation</li>
<li class="">Check if installation was successful</li>
<li class="">If the previous step finished with a pass rate of &gt; X% then install the same software on the remaining devices</li>
</ol>]]></content:encoded>
            <author>reuben.d.miller@gmail.com (Reuben Miller)</author>
            <category>c8y</category>
            <category>demo</category>
        </item>
    </channel>
</rss>