<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: pr4th4m</title>
    <description>The latest articles on Forem by pr4th4m (@pratham).</description>
    <link>https://forem.com/pratham</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F162703%2F80a7d381-6fc9-42f8-a141-434829129ec1.jpeg</url>
      <title>Forem: pr4th4m</title>
      <link>https://forem.com/pratham</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pratham"/>
    <language>en</language>
    <item>
      <title>Tmux - fast window switching across sessions</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Mon, 06 May 2019 02:46:38 +0000</pubDate>
      <link>https://forem.com/pratham/tmux-fast-window-switching-across-sessions-3n0c</link>
      <guid>https://forem.com/pratham/tmux-fast-window-switching-across-sessions-3n0c</guid>
      <description>&lt;h3&gt;
  
  
  Tmux window switching
&lt;/h3&gt;

&lt;p&gt;Tmux already makes it easy to switch windows in a session, however, it's hard to switch to windows from another session. To make window switching across sessions fast we can leverage &lt;a href="https://github.com/junegunn/fzf"&gt;fzf&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;fzf-tmux&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  tmux list-windows &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"#S:#I-#W"&lt;/span&gt; | fzf-tmux | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"-"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 1 | xargs tmux switch-client &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Binding it with &lt;code&gt;.tmux.conf&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;bind&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; ^f run-shell &lt;span class="s2"&gt;"tmux list-windows -a -F &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;##S:##I-##W&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; | fzf-tmux | cut -d &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -f 1 | xargs tmux switch-client -t"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>tmux</category>
      <category>fzf</category>
    </item>
    <item>
      <title>Stream cli output over http</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Mon, 06 May 2019 02:43:55 +0000</pubDate>
      <link>https://forem.com/pratham/stream-cli-output-over-http-258i</link>
      <guid>https://forem.com/pratham/stream-cli-output-over-http-258i</guid>
      <description>&lt;h3&gt;
  
  
  Runnel
&lt;/h3&gt;

&lt;p&gt;A program to stream any command line output over http. This is useful when we want to display command output on client side. One such use case can be displaying live logs in browser which are running inside a container on server side.&lt;/p&gt;

&lt;h4&gt;
  
  
  Installation:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Using docker (recommended)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git clone https://github.com/VeritasOS/runnel.git
  &lt;span class="nb"&gt;cd &lt;/span&gt;runnel

  &lt;span class="c"&gt;# build docker image&lt;/span&gt;
  docker build &lt;span class="nt"&gt;-t&lt;/span&gt; runnel:latest &lt;span class="nb"&gt;.&lt;/span&gt;

  &lt;span class="c"&gt;# start runnel server&lt;/span&gt;
  docker run &lt;span class="nt"&gt;--name&lt;/span&gt; runnel &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:9090:9090 runnel:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using binary (not recommended, because system dependencies are taken care in docker file on behalf of you)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git clone https://github.com/VeritasOS/runnel.git
  &lt;span class="nb"&gt;cd &lt;/span&gt;runnel

  ./bin/linux_64/runnel_server &lt;span class="nt"&gt;-p&lt;/span&gt; localhost:9090
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Trigger below commands to get live stream
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# Fire command with curl&lt;/span&gt;
  curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"cmd":"ping -c 3 google.com"}'&lt;/span&gt; http://localhost:9090/command

  &lt;span class="c"&gt;# Get live output stream&lt;/span&gt;
  &lt;span class="c"&gt;# replace uuid with one which you get from above command&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="s1"&gt;'http://localhost:9090/stream/fd4b1a38-94f4-4eba-80e7-50578ac4baae'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.response'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Package:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: Install redis server&lt;/li&gt;
&lt;li&gt;Use as golang package
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# Get lib&lt;/span&gt;
  go get github.com/veritasos/runnel/runnel

  &lt;span class="c"&gt;# Fire command&lt;/span&gt;
  client :&lt;span class="o"&gt;=&lt;/span&gt; runnel.NewClient&lt;span class="o"&gt;()&lt;/span&gt;
  key, err :&lt;span class="o"&gt;=&lt;/span&gt; client.RunCommand&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ping"&lt;/span&gt;, &lt;span class="s2"&gt;"-c 2 google.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

  &lt;span class="c"&gt;# Get output stream&lt;/span&gt;
  client :&lt;span class="o"&gt;=&lt;/span&gt; runnel.NewClient&lt;span class="o"&gt;()&lt;/span&gt;
  output, err :&lt;span class="o"&gt;=&lt;/span&gt; client.Stream&lt;span class="o"&gt;(&lt;/span&gt;key, 10&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Detailed documentation:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A much more detailed documentation is provided here &lt;a href="https://github.com/VeritasOS/runnel"&gt;&lt;strong&gt;runnel&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/VeritasOS/runnel"&gt;&lt;strong&gt;Feel free to Contribute back&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>docker</category>
    </item>
    <item>
      <title>OpenEMM python client</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Fri, 03 May 2019 09:36:19 +0000</pubDate>
      <link>https://forem.com/pratham/openemm-python-client-2n6l</link>
      <guid>https://forem.com/pratham/openemm-python-client-2n6l</guid>
      <description>&lt;h3&gt;
  
  
  Py-OpenEMM
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.openemm.org"&gt;&lt;strong&gt;OpenEMM&lt;/strong&gt;&lt;/a&gt; is a feature-rich web-based enterprise application for email marketing, newsletters and service mails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-requisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 2.7 or higher&lt;/li&gt;
&lt;li&gt;Python Suds 0.4 or higher&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone repo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git clone https://github.com/pratz/py-openemm.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move to directory where you have cloned the repo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;cd &lt;/span&gt;py-openemm/pyopenemm
  vi config.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open &lt;code&gt;config.py&lt;/code&gt; file and enter openemm wsdl url, username and password
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  OPENEMM_URL &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'http://127.0.0.1:8080/cms_services/urn:agnitas-webservice?wsdl'&lt;/span&gt;
  WEBSERVICE_USER &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test_user'&lt;/span&gt;
  WEBSERVICE_PASSWORD &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test_123'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create client connection
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pyopenemm.connection.connect&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;
  &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;# connect to webservice , returned is suds client
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Get OpenEMM client
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pyopenemm.webservice.service&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenEMM&lt;/span&gt;
  &lt;span class="n"&gt;openemm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenEMM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Find subscriber
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# get subcriber by email
&lt;/span&gt;  &lt;span class="n"&gt;subscriber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openemm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_subscriber&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'test@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Get subscriber details
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;subscriber_details&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openemm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_subscriber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add new subcriber
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;user_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;'openemm@openemm.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'firstname'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;'openemmfirstname'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'lastname'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;'openemmlastname'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'gender'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;new_subscriber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openemm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_subscriber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# add new subscriber to openemm
&lt;/span&gt;
  &lt;span class="c1"&gt;# Four parameters of add_subscriber() method
&lt;/span&gt;  &lt;span class="c1"&gt;# user_dict = Dictionary containing user information
&lt;/span&gt;  &lt;span class="c1"&gt;# double_check - If True, check if subscriber is already in database
&lt;/span&gt;  &lt;span class="c1"&gt;# key_column - column used for double_check
&lt;/span&gt;  &lt;span class="c1"&gt;# overwrite - If True, subscriber gets updated
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/pratz/py-openemm"&gt;&lt;strong&gt;Feel free to Contribute back&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>openemm</category>
      <category>python</category>
    </item>
    <item>
      <title>Netrc python client</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Fri, 03 May 2019 09:31:07 +0000</pubDate>
      <link>https://forem.com/pratham/netrc-python-client-ccj</link>
      <guid>https://forem.com/pratham/netrc-python-client-ccj</guid>
      <description>&lt;h3&gt;
  
  
  What is Netrc file ?
&lt;/h3&gt;

&lt;p&gt;Netrc file contains user credentials and is used to auto-login. It is usually located in users home directory &lt;code&gt;.netrc&lt;/code&gt; but location can be overridden with &lt;code&gt;NETRC&lt;/code&gt; environment variable. Netrc also supports macros &lt;code&gt;macdef&lt;/code&gt; to automate tasks. Netrc can be used with ftp, curl, git etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Netrc file sample:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ~ &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .netrc
  machine product.company.com
  login first.last
  password secret-password

  macdef macro-name1
  command1
  command2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Get client:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  curl &lt;span class="nt"&gt;-o&lt;/span&gt; netrc_client.py  &lt;span class="s2"&gt;"https://gist.githubusercontent.com/pratz/789dc165c6d9f79be86608547b128c69/raw/41fb7796f6b6d0a09ac5ddeaf8c79de30a2387ed/NetRc%2520-%2520read,%2520write,%2520update"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Client compatibility:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux/Mac&lt;/li&gt;
&lt;li&gt;Python 2.7.x&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# create client
&lt;/span&gt;  &lt;span class="n"&gt;netrc_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NetRc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="s"&gt;"product.company.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"first.last"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"secret-password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# account is optional
&lt;/span&gt;          &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# create or update file content
&lt;/span&gt;  &lt;span class="n"&gt;netrc_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_or_update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;# Custom file path (not recommended, as other programs might look for .netrc in users home directory)
&lt;/span&gt;  &lt;span class="n"&gt;NETRC_FILE_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;
  &lt;span class="n"&gt;netrc_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_or_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NETRC_FILE_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netrc stores credentials in plan text. This is how netrc is meant to be ;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Its a good idea to use netrc when you have token based authentication.&lt;/li&gt;
&lt;li&gt;Automation for service accounts with token based authentication.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>netrc</category>
    </item>
    <item>
      <title>Artifactory python client</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Fri, 03 May 2019 09:22:34 +0000</pubDate>
      <link>https://forem.com/pratham/artifactory-python-client-20i0</link>
      <guid>https://forem.com/pratham/artifactory-python-client-20i0</guid>
      <description>&lt;h3&gt;
  
  
  Py-Artifactory
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.jfrog.com/artifactory"&gt;&lt;strong&gt;Artifactory&lt;/strong&gt;&lt;/a&gt; is a artifact repository manager which supports software packages created by different technologies.&lt;br&gt;
It can also be integrated with major CI/CD and DevOps tools.&lt;br&gt;
This article shows how we can communicate with artifactory using a python api client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-requisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 2.7 or higher&lt;/li&gt;
&lt;li&gt;libxml2/libxslt (will be deprecated in future releases)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# Debian based&lt;/span&gt;
  &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;libxml2-dev libxslt1-dev

  &lt;span class="c"&gt;# RedHat based&lt;/span&gt;
  &lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;libxml2-devel libxslt-devel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fire-up below command in terminal, &lt;code&gt;tag&lt;/code&gt; specifies a version number.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  pip &lt;span class="nb"&gt;install &lt;/span&gt;git+https://github.com/veritasos/py-artifactory.git@&amp;lt;tag&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create client instance
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;artifactory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Artifactory&lt;/span&gt;
  &lt;span class="n"&gt;artifactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Artifactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://127.0.0.1:8081"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;List users
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;user_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;artifactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Get user
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;artifactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user.name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create user
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;artifactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"first.last"&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"first.last@testartifactory.com"&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"readers"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And much more ......
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Artifactory Users
  Artifactory Groups
  Artifactory Permissions
  Artifactory Repositories
  Artifactory Repository Replication
  Artifactory LDAP
  Artifactory User Api Keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Detailed documentation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A much more detailed documentation is provided here &lt;a href="https://github.com/VeritasOS/py-artifactory"&gt;&lt;strong&gt;py-artifactory&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pratz/py-openemm"&gt;&lt;strong&gt;Feel free to Contribute back&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>artifactory</category>
    </item>
    <item>
      <title>Git login with Netrc</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Thu, 02 May 2019 13:18:02 +0000</pubDate>
      <link>https://forem.com/pratham/git-login-with-netrc-2fbe</link>
      <guid>https://forem.com/pratham/git-login-with-netrc-2fbe</guid>
      <description>&lt;h4&gt;
  
  
  What is Netrc file ?
&lt;/h4&gt;

&lt;p&gt;Netrc file contains user credentials and is used to auto-login. It is usually located in users home directory &lt;code&gt;.netrc&lt;/code&gt; but location can be overridden with &lt;code&gt;NETRC&lt;/code&gt; environment variable. Netrc also supports macros &lt;code&gt;macdef&lt;/code&gt; to automate tasks. Netrc can be used with ftp, curl, git etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  Netrc file:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create file named &lt;code&gt;.netrc&lt;/code&gt; in home directory.&lt;/li&gt;
&lt;li&gt;Lets consider your git server is hosted on domain &lt;code&gt;git.company.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ~ &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .netrc
  machine git.company.com
  login first.last
  password secret-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Secure netrc file:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;As &lt;code&gt;.netrc&lt;/code&gt; is used to store credentials, lets secure the file.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ~ &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;0600 ~/.netrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, next time when you use git for domain &lt;code&gt;git.company.com&lt;/code&gt;, git should pick up the credentials on behalf of you ;)&lt;/p&gt;

&lt;h4&gt;
  
  
  Warning:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Netrc stores credentials in plan text. This is how netrc is meant to be ;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use case:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Its a good idea to use netrc when you have token based authentication.&lt;/li&gt;
&lt;li&gt;Automation for service accounts with token based authentication.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>netrc</category>
    </item>
    <item>
      <title>Custom git credential helper</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Thu, 02 May 2019 13:08:34 +0000</pubDate>
      <link>https://forem.com/pratham/custom-git-credential-helper-pfa</link>
      <guid>https://forem.com/pratham/custom-git-credential-helper-pfa</guid>
      <description>&lt;h3&gt;
  
  
  Git credential helper:
&lt;/h3&gt;

&lt;p&gt;Git credential helper is used to save user credentials, so that user does not require to enter credentials on each git operation.&lt;br&gt;
Git provides few default git credential helpers, &lt;a href="https://git-scm.com/docs/gitcredentials"&gt;see how to use them&lt;/a&gt;.&lt;br&gt;
This blog will demonstrate on how to build custom git credential helper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple python cli:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's write a python cli called &lt;code&gt;auth_helper.py&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="c1"&gt;#!/usr/bin/env python
&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;argparse&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Credential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
          &lt;span class="c1"&gt;# logic to get username/password from auth file
&lt;/span&gt;          &lt;span class="k"&gt;pass&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
          &lt;span class="c1"&gt;# logic to store username/password to auth file
&lt;/span&gt;          &lt;span class="c1"&gt;# its better to encrypt password if its in plain text
&lt;/span&gt;          &lt;span class="k"&gt;pass&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;erase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
          &lt;span class="c1"&gt;# logic to delete auth file
&lt;/span&gt;          &lt;span class="k"&gt;pass&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
      &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'operation'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Git action to be performed (get|store|erase)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# parser all arguments
&lt;/span&gt;      &lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="c1"&gt;# get credentials
&lt;/span&gt;      &lt;span class="n"&gt;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Credential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username={0}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
          &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password={0}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"store"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="c1"&gt;# if credentials are already stored do not store again
&lt;/span&gt;      &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"erase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;erase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;"Invalid git operation"&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This cli takes three git operations as cli arguments &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;store&lt;/code&gt; and &lt;code&gt;erase&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;These arguments are not coincident, they are used by git. Let's know more about them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Git credentials store:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git credentials store looks for three arguments

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get&lt;/code&gt;: called when triggered git pull, git fetch, git push etc.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;store&lt;/code&gt;: called when triggered git pull, git fetch, git push etc.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;erase&lt;/code&gt;: if our provided credentials fail, git will fallback to its own credentials prompt, if this fails as well &lt;code&gt;erase&lt;/code&gt; is called.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Git helper configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To configure our cli as git helper, trigger the below command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git config &lt;span class="nt"&gt;--global&lt;/span&gt; credential.https://git.company.com.helper &lt;span class="s2"&gt;"./path/to/cli/auth_helper.py"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This will define &lt;code&gt;auth_helper.py&lt;/code&gt; under &lt;code&gt;credential&lt;/code&gt; section of &lt;code&gt;.gitconfig&lt;/code&gt; file (user's home directory).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;https://git.company.com&lt;/code&gt; is the domain where git is hosted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Done!!&lt;/strong&gt; Next time we use git, our &lt;code&gt;auth_helper.py&lt;/code&gt; should provide credentials for git authorization.&lt;/p&gt;

</description>
      <category>git</category>
      <category>python</category>
    </item>
    <item>
      <title>Custom ansible modules</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Thu, 02 May 2019 12:58:56 +0000</pubDate>
      <link>https://forem.com/pratham/custom-ansible-modules-1gkd</link>
      <guid>https://forem.com/pratham/custom-ansible-modules-1gkd</guid>
      <description>&lt;h3&gt;
  
  
  How to write ansible custom modules
&lt;/h3&gt;

&lt;p&gt;Ansible modules are easy way to interact between an existing application and ansible playbook. This blog covers how to write your own ansible module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Module&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a python file called &lt;code&gt;greet.py&lt;/code&gt; with following content
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
      &lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AnsibleModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;argument_spec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"str"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;supports_check_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="c1"&gt;# get module params
&lt;/span&gt;      &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fail_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"It's bad not to greet someone"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;ansible.module_utils.basic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AnsibleModule&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;File name &lt;code&gt;greet.py&lt;/code&gt; is considered as ansible module.&lt;/li&gt;
&lt;li&gt;Arguments defined in ansible playbooks will be parsed by &lt;code&gt;AnsibleModule&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;Ansible module always returns json, for convenience ansible provides two methods, one for success and other for failure
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# For success
&lt;/span&gt;  &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# For failure
&lt;/span&gt;  &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fail_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"It's bad not to greet someone"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an ansible playbook called &lt;code&gt;playbook.yml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;touch &lt;/span&gt;playbook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create directory &lt;code&gt;library&lt;/code&gt; alongside &lt;code&gt;playbook.yml&lt;/code&gt; and copy &lt;code&gt;greet.py&lt;/code&gt; to &lt;code&gt;library&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mkdir &lt;/span&gt;library
  &lt;span class="nb"&gt;cp &lt;/span&gt;greet.py library
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now our directory structure should look like
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  library
      |- greet.py
  playbook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We can now use &lt;code&gt;greet&lt;/code&gt; module with our &lt;code&gt;playbook.yml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="s"&gt;---&lt;/span&gt;
  &lt;span class="s"&gt;- hosts&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
    &lt;span class="s"&gt;tasks&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lets start greeting&lt;/span&gt;
      &lt;span class="na"&gt;greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Good&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;morning"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>ansible</category>
    </item>
    <item>
      <title>Setup NFS and SMB server on Raspberry Pi</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Thu, 02 May 2019 12:44:16 +0000</pubDate>
      <link>https://forem.com/pratham/setup-nfs-and-smb-server-on-raspberry-pi-3ml6</link>
      <guid>https://forem.com/pratham/setup-nfs-and-smb-server-on-raspberry-pi-3ml6</guid>
      <description>&lt;h3&gt;
  
  
  NFS server
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nfs-common nfs-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create directory you wanna share
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mkdir&lt;/span&gt; /media/storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit file &lt;code&gt;/etc/exports&lt;/code&gt; with below content
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  /media/storage 192.168.1.0/24&lt;span class="o"&gt;(&lt;/span&gt;rw,all_squash,insecure,no_subtree_check&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="c"&gt;# &amp;lt;directory&amp;gt; &amp;lt;who_can_access&amp;gt; &amp;lt;options&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Restart services
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;service nfs restart
  /etc/init.d/nfs-kernel-server restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Connecting from client (MacOS)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mkdir&lt;/span&gt; /Users/username/nfs_shared
  &lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"resvport"&lt;/span&gt; 192.168.1.9:/media/storage /Users/username/nfs_shared
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Samba server
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;samba samba-common-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create samba password for system user
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;smbpasswd &lt;span class="nt"&gt;-a&lt;/span&gt; pi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create directory you wanna share
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mkdir&lt;/span&gt; /media/storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit file &lt;code&gt;/etc/samba/smb.conf&lt;/code&gt; with below content
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="o"&gt;[&lt;/span&gt;PI]
  comment &lt;span class="o"&gt;=&lt;/span&gt; Pi workspace
  path &lt;span class="o"&gt;=&lt;/span&gt; /media/storage
  create mask &lt;span class="o"&gt;=&lt;/span&gt; 0775
  directory mask &lt;span class="o"&gt;=&lt;/span&gt; 0775
  &lt;span class="nb"&gt;read &lt;/span&gt;only &lt;span class="o"&gt;=&lt;/span&gt; no
  browseable &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;yes
  &lt;/span&gt;public &lt;span class="o"&gt;=&lt;/span&gt; no
  force user &lt;span class="o"&gt;=&lt;/span&gt; pi
  only guest &lt;span class="o"&gt;=&lt;/span&gt; no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Restart service
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;service samba restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Connecting from client (MacOS)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mkdir&lt;/span&gt; /Users/username/smb_shared
  mount &lt;span class="nt"&gt;-t&lt;/span&gt; smbfs //pi@192.168.1.9/pi /Users/username/smb_shared
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nfs</category>
      <category>smb</category>
      <category>raspberrypi</category>
    </item>
    <item>
      <title>On-prem ansible galaxy</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Thu, 02 May 2019 11:12:51 +0000</pubDate>
      <link>https://forem.com/pratham/on-prem-ansible-galaxy-6b</link>
      <guid>https://forem.com/pratham/on-prem-ansible-galaxy-6b</guid>
      <description>&lt;p&gt;Generic ansible roles can be shared through &lt;a href="https://galaxy.ansible.com"&gt;ansible galaxy&lt;/a&gt;, however, its hard to access ansible-galaxy from within corporate network. A good alternative is to host something similar to ansible-galaxy on-prem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-prem galaxy repository&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For this blog stash is considered (&lt;a href="https://stash.company.com"&gt;https://stash.company.com&lt;/a&gt;), however, gitlab, gogs or similar should work as well&lt;/li&gt;
&lt;li&gt;Create a new project on stash &lt;code&gt;Ansible Galaxy&lt;/code&gt; with key &lt;code&gt;AG&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create repo for each generic ansbile role.&lt;/li&gt;
&lt;li&gt;All generic ansbile roles can be browsed at &lt;a href="https://stash.company.com/projects/AG"&gt;https://stash.company.com/projects/AG&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Now these roles can be used with multiple ansible playbooks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new file &lt;code&gt;requirements.yml&lt;/code&gt; alongside ansible &lt;code&gt;playbook.yml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For this blog purposes I am considering &lt;code&gt;awscli&lt;/code&gt; as an generic ansible role with its own repo, which resides in our newly created stash project &lt;code&gt;Ansible Galaxy (AG)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy/paste below content to &lt;code&gt;requirements.yml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="s"&gt;---&lt;/span&gt;
  &lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;awscli&lt;/span&gt;
  &lt;span class="s"&gt;src&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git+https://stash.company.com/scm/ag/awscli&lt;/span&gt;
  &lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
  &lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/.ansible/roles&lt;/span&gt;

  &lt;span class="s"&gt;# name - name of role&lt;/span&gt;
  &lt;span class="s"&gt;# src - location of role&lt;/span&gt;
  &lt;span class="s"&gt;# version - which branch the role should be installed from&lt;/span&gt;
  &lt;span class="s"&gt;# path - where we want to install roles&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;requirements.yml&lt;/code&gt; files acts as a role dependency list for our &lt;code&gt;playbook.yml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once we define our ansible playbook dependencies, its time to install them.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;ansible-galaxy &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.yml
  &lt;span class="c"&gt;# NOTE: no need to install ansible-galaxy seperately, it ships with default ansible installation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Done! all the roles are now installed and ready to be used by our &lt;code&gt;playbook.yml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>ansible</category>
    </item>
    <item>
      <title>SemVer versioning utility</title>
      <dc:creator>pr4th4m</dc:creator>
      <pubDate>Thu, 02 May 2019 10:57:21 +0000</pubDate>
      <link>https://forem.com/pratham/semver-versioning-utility-1dgk</link>
      <guid>https://forem.com/pratham/semver-versioning-utility-1dgk</guid>
      <description>&lt;h3&gt;
  
  
  Versioner
&lt;/h3&gt;

&lt;p&gt;Version reader/writer for popular package managers as per &lt;a href="https://semver.org/"&gt;SemVer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  pip &lt;span class="nb"&gt;install &lt;/span&gt;git+https://github.com/VeritasOS/versioner.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Current support&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;dep&lt;/li&gt;
&lt;li&gt;json&lt;/li&gt;
&lt;li&gt;toml&lt;/li&gt;
&lt;li&gt;yaml (currently multi doc in single file not supported)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read version (run command from project root)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner &lt;span class="nb"&gt;read &lt;/span&gt;npm  &lt;span class="c"&gt;# projects based on npm&lt;/span&gt;
  &lt;span class="s2"&gt;"0.0.1"&lt;/span&gt;

  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner &lt;span class="nb"&gt;read &lt;/span&gt;dep  &lt;span class="c"&gt;# golang projects&lt;/span&gt;
  &lt;span class="s2"&gt;"0.1.1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Write version (run command from project root)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# package.json&lt;/span&gt;
  ....
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"1.1.1"&lt;/span&gt;,
  ....

  &lt;span class="c"&gt;# Release patch version&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner write npm &lt;span class="nt"&gt;--inc-patch&lt;/span&gt;

  &lt;span class="c"&gt;# package.json&lt;/span&gt;
  ....
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"1.1.2"&lt;/span&gt;,
  ....

  &lt;span class="c"&gt;# Release minor version&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner write npm &lt;span class="nt"&gt;--inc-minor&lt;/span&gt;

  ....
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"1.2.0"&lt;/span&gt;,
  ....

  &lt;span class="c"&gt;# Release major version&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner write npm &lt;span class="nt"&gt;--inc-major&lt;/span&gt;

  ....
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"2.0.0"&lt;/span&gt;,
  ....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Read version from custom file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner &lt;span class="nb"&gt;read &lt;/span&gt;yaml &lt;span class="nt"&gt;--file&lt;/span&gt; /root/app/version.yaml &lt;span class="nt"&gt;--key-depth&lt;/span&gt; metadata,version
  0.0.2

  version.yaml
  &lt;span class="nt"&gt;---&lt;/span&gt;
  metadata:
    version: 0.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Write version to custom file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; versioner write yaml &lt;span class="nt"&gt;--inc-major&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; /root/app/version.yaml &lt;span class="nt"&gt;--key-depth&lt;/span&gt; metadata,version

  version.yaml
  &lt;span class="nt"&gt;---&lt;/span&gt;
  metadata:
    version: 1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Development
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git clone https://github.com/VeritasOS/versioner.git
  &lt;span class="nb"&gt;cd &lt;/span&gt;versioner
  pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This utility is tested for npm and dep.&lt;/li&gt;
&lt;li&gt;Read/write for custom file may break, please feel free to send a patch.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/VeritasOS"&gt;
        VeritasOS
      &lt;/a&gt; / &lt;a href="https://github.com/VeritasOS/versioner"&gt;
        versioner
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Version reader/writer for popular package managers as per SemVer
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h3&gt;
Versioner&lt;/h3&gt;
&lt;p&gt;Version reader/writer for popular package managers as per &lt;a href="https://semver.org/" rel="nofollow"&gt;SemVer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;&lt;pre&gt;&lt;code&gt;pip install git+https://github.com/VeritasOS/versioner.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Current support&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;dep&lt;/li&gt;
&lt;li&gt;json&lt;/li&gt;
&lt;li&gt;toml&lt;/li&gt;
&lt;li&gt;yaml (currently multi doc in single file not supported)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Read version (run command from project root)&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;&lt;pre&gt;&lt;code&gt;  &amp;gt; versioner read npm  # projects based on npm
  "0.0.1"
  &amp;gt; versioner read dep  # golang projects
  "0.1.1"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write version (run command from project root)&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;&lt;pre&gt;&lt;code&gt;  # package.json
  ....
  "version": "1.1.1",
  ....

  # Release patch version
  &amp;gt; versioner write npm --inc-patch

  # package.json
  ....
  "version": "1.1.2",
  ....

  # Release minor version
  &amp;gt; versioner write npm --inc-minor

  ....
  "version": "1.2.0",
  ....

  # Release major version
  &amp;gt; versioner write npm --inc-major

  ....
  "version": "2.0.0",
  ....
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read version from custom file&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;&lt;pre&gt;&lt;code&gt;  &amp;gt; versioner read yaml --file /root/app/version.yaml --key-depth metadata,version
  0.0.2

  version.yaml
  ---
  metadata:
    version: 0.0.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write version to custom file&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;&lt;pre&gt;&lt;code&gt;  &amp;gt; versioner write yaml --inc-major --file /root/app/version.yaml --key-depth metadata,version

  version.yaml
  ---
  metadata:
    version: 1.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Development&lt;/h4&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;
&lt;pre&gt;&lt;code&gt;git clone&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/VeritasOS/versioner"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>python</category>
      <category>semver</category>
      <category>npm</category>
      <category>dep</category>
    </item>
  </channel>
</rss>
