<?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>DEV Community: Artem</title>
    <description>The latest articles on DEV Community by Artem (@secure_daily).</description>
    <link>https://dev.to/secure_daily</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%2F198363%2Ffc18522d-4192-4bb6-9ba9-400ee29efc79.jpg</url>
      <title>DEV Community: Artem</title>
      <link>https://dev.to/secure_daily</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/secure_daily"/>
    <language>en</language>
    <item>
      <title>Trivy Vulnerability Scans Adnvanced Filtering</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Thu, 12 Dec 2024 18:50:10 +0000</pubDate>
      <link>https://dev.to/secure_daily/trivy-vulnerability-scans-adnvanced-filtering-em8</link>
      <guid>https://dev.to/secure_daily/trivy-vulnerability-scans-adnvanced-filtering-em8</guid>
      <description>&lt;p&gt;Hi there!&lt;/p&gt;

&lt;p&gt;It's been a while since I posted anything, but it is all cause of the good reasons. The last 2 years were busy for me both at work and day-to-day.&lt;/p&gt;

&lt;p&gt;Anyway, I just wanted to share the cool feature I discovered in Trivy that really sets it apart from all other OSS security scanners. I am talking about the advanced filtering, that is using Open Policy Agent and Rego scripts to make decisions on what should be ignored from the scan results. It is described in details in the &lt;a href="https://trivy.dev/latest/docs/configuration/filtering/#by-rego" rel="noopener noreferrer"&gt;Trivy's official documentation&lt;/a&gt;, and although it is an experimental feature, it has been around since older version of Trivy.&lt;/p&gt;

&lt;p&gt;I want to wrap this short blog post, by sharing a Rego script allowing to filter the CVEs based on the grace period:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rego"&gt;&lt;code&gt;&lt;span class="ow"&gt;package&lt;/span&gt; &lt;span class="n"&gt;trivy&lt;/span&gt;

&lt;span class="ow"&gt;import&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trivy&lt;/span&gt;

&lt;span class="ow"&gt;default&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="n"&gt;now_ns&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now_ns&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;days_7_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000000000&lt;/span&gt;
&lt;span class="n"&gt;days_30_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000000000&lt;/span&gt;
&lt;span class="n"&gt;days_90_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000000000&lt;/span&gt;
&lt;span class="n"&gt;days_180_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;180&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000000000&lt;/span&gt;


&lt;span class="n"&gt;published_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublishedDate&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Severity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"CRITICAL"&lt;/span&gt;
    &lt;span class="n"&gt;published_date_ns&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_rfc3339_ns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now_ns&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;published_date_ns&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;days_7_ns&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Severity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"HIGH"&lt;/span&gt;
    &lt;span class="n"&gt;published_date_ns&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_rfc3339_ns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now_ns&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;published_date_ns&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;days_30_ns&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Severity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"MEDIUM"&lt;/span&gt;
    &lt;span class="n"&gt;published_date_ns&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_rfc3339_ns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now_ns&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;published_date_ns&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;days_90_ns&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Severity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"LOW"&lt;/span&gt;
    &lt;span class="n"&gt;published_date_ns&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_rfc3339_ns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now_ns&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;published_date_ns&lt;/span&gt;
    &lt;span class="n"&gt;time_diff_ns&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;days_180_ns&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following script queries the results of the scans and checks for severity and evaluates against the set grace policy.&lt;/p&gt;

&lt;p&gt;It is really exciting to have this capability in the OSS, since normally you would have to pay for premium subscription to get a scanner use advanced filtering in the policies.&lt;/p&gt;

</description>
      <category>trivy</category>
      <category>vulnerabilities</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Terraform Interpolation vs. Directives</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Fri, 01 Jul 2022 00:14:54 +0000</pubDate>
      <link>https://dev.to/secure_daily/terraform-interpolation-vs-directives-45f0</link>
      <guid>https://dev.to/secure_daily/terraform-interpolation-vs-directives-45f0</guid>
      <description>&lt;p&gt;Every Terraform user should be familiar with HashiCorp Language (HCL) aka Terraform &lt;strong&gt;interpolation syntax&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let say I have a variable defined as &lt;code&gt;filename&lt;/code&gt;, then interpolation allows me to do stuff like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"local_file"&lt;/span&gt; &lt;span class="s2"&gt;"index"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.filename}.txt"&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"foo!"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Terraform official website says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Interpolation] evaluates the expression given between the markers, converts the result to a string if necessary, and then inserts it into the final string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, it can do some elementary operation and dump result as a string. &lt;/p&gt;

&lt;p&gt;This is neat, and can be helpful if we want to add suffix or prefix to an EC2 instance, but what if we are tasked with generating a config file dynamically with unknown number of nested blocks?&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;directives&lt;/strong&gt; come into play!&lt;/p&gt;

&lt;p&gt;The Terraform docs have this short definition of the directive:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[It] allows for conditional results and iteration over collections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is kinda like &lt;code&gt;for_each&lt;/code&gt;, but inside of string rather than resource.&lt;/p&gt;

&lt;p&gt;An example should make things clear!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"filename"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"index.html"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"facts"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"fun"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"hard"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"complex_facts"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"h2"&lt;/span&gt;
      &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FUN!"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"h1"&lt;/span&gt;
      &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"EASY!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"local_file"&lt;/span&gt; &lt;span class="s2"&gt;"index_html"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${path.module}/${var.filename}"&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOT&lt;/span&gt;&lt;span class="sh"&gt;
    &amp;lt;html&amp;gt;
    %{for fact in var.facts}
      &amp;lt;p&amp;gt;Terraform is ${fact}&amp;lt;/p&amp;gt;
    %{endfor}

    %{for fact in var.complex_facts}
      &amp;lt;${fact.element}&amp;gt;Terraform is ${fact.content}&amp;lt;/${fact.element}&amp;gt;
    %{endfor}
    &amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;  EOT
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see how list &lt;code&gt;facts&lt;/code&gt; is used to generate HTML &lt;/p&gt;
&lt;p&gt; elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;fact&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facts&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Terraform&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;endfor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same syntax can be used on objects, like with in &lt;code&gt;complex_facts&lt;/code&gt; case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;fact&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complex_facts&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Terraform&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;endfor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting HTML file is pretty ugly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Terraform is fun&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Terraform is hard&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;



      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Terraform is FUN!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Terraform is EASY!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be used to generate tiny and ugly HTMLs (although there are better tools for this purpose), but it can also be used for more complex configuration files! &lt;/p&gt;

&lt;p&gt;It can also be used to replace ternary expression, which some people find hard to read.&lt;/p&gt;

&lt;p&gt;This interpolation sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"local_file"&lt;/span&gt; &lt;span class="s2"&gt;"txt"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${path.module}/file.txt"&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOT&lt;/span&gt;&lt;span class="sh"&gt;
    ${ var.content != "" ? var.content : "NO CONTENT PROVIDED"}
&lt;/span&gt;&lt;span class="no"&gt;  EOT
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be replace by the following directives sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"local_file"&lt;/span&gt; &lt;span class="s2"&gt;"txt"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${path.module}/file.txt"&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOT&lt;/span&gt;&lt;span class="sh"&gt;
    %{ if var.content != "" }${var.content}%{ else }NO CONTENT PROVIDED!%{ endif }
&lt;/span&gt;&lt;span class="no"&gt;  EOT
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all for today! Have fun hacking Terraform!&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Why NOT TO Ship NodeJS Containers With NPM?</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Thu, 06 Jan 2022 15:37:42 +0000</pubDate>
      <link>https://dev.to/secure_daily/why-ship-nodejs-containers-with-npm-33pp</link>
      <guid>https://dev.to/secure_daily/why-ship-nodejs-containers-with-npm-33pp</guid>
      <description>&lt;p&gt;There is a number of great guides on "containerizing" NodeJS applications, including &lt;a href="https://snyk.io/blog/10-best-practices-to-containerize-nodejs-web-applications-with-docker/" rel="noopener noreferrer"&gt;this one from Snyk&lt;/a&gt;. However, I am yet to see a resource recommending to omit NPM from the final container image.&lt;/p&gt;

&lt;p&gt;Let's say I have the following "dummy" application:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bla bla bla&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&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;package.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node index.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One common way to structure a Dockerfile for this app would be using two stage build. First stage, installing dependencies; and second creating the final image. Both stages are using Alpine image with pre-installed NodeJS and NPM. With our simple app, we can even omit the first step, but let's pretend we need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bad.Dockerfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:16-alpine3.15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package-lock.json .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--production&lt;/span&gt;

&lt;span class="c"&gt;# Final stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:16-alpine3.15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;final&lt;/span&gt;

&lt;span class="c"&gt;# Setup application&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /app/simple-server
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app/simple-server&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build node_modules node_modules&lt;/span&gt;

&lt;span class="c"&gt;# Run application&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["node", "index.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see NPM will be shipped with the final container image. So what's the problem here?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The issue is the final image will have the dependency that is not used, but you would have to maintain it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Not a big deal? It actually is, and can potentially become a blocker preventing to ship your application to production (or other environment depending on security controls in place). A good example is CVE-2021-3807. &lt;a href="https://github.com/npm/cli/issues/3785" rel="noopener noreferrer"&gt;There is a GitHub Issue open&lt;/a&gt;, where engineers complaining how vulnerability presented in NPM blocks them in one or another way.&lt;/p&gt;




&lt;p&gt;The solution here is simple - omit NPM from your final image. In Docker multi-stage build, it would look very similar to the &lt;em&gt;bad&lt;/em&gt; example. The main difference is the final image is bare Alpine, and only NodeJS is installed as build step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;good.Dockerfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:16-alpine3.15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package-lock.json .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--production&lt;/span&gt;

&lt;span class="c"&gt;# Final stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;alpine:3.15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;final&lt;/span&gt;

&lt;span class="c"&gt;# Upgrade APK&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk &lt;span class="nt"&gt;--no-cache&lt;/span&gt; add &lt;span class="nt"&gt;--upgrade&lt;/span&gt; nodejs~16

&lt;span class="c"&gt;# Setup application&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /app/simple-server
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app/simple-server&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build node_modules node_modules&lt;/span&gt;

&lt;span class="c"&gt;# Run application&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["node", "index.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another benefit of excluding NPM from the final image is reduced size. The "dummy" server without NPM is 53.9MB, while with the package manager 112MB!&lt;/p&gt;

&lt;p&gt;Not much else to say here. &lt;em&gt;If you still have NPM in your final container image, ask yourself why!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Thank you for reading this article, and I would like to see the feedback on this one! Please let me know in comments what are YOUR legitimate reasons for having NPM in the final container image. &lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>discuss</category>
      <category>security</category>
    </item>
    <item>
      <title>Installation Using Operator | Prisma Cloud Compute</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Tue, 14 Dec 2021 05:12:08 +0000</pubDate>
      <link>https://dev.to/secure_daily/install-prisma-cloud-compute-using-operator-5ei5</link>
      <guid>https://dev.to/secure_daily/install-prisma-cloud-compute-using-operator-5ei5</guid>
      <description>&lt;p&gt;Prisma Cloud Compute is a self-hosted solution to secure containerized workflows. "Self-hosted" means organizations have to deploy and manage updates themselves.&lt;/p&gt;

&lt;p&gt;For Kubernetes and OpenShift deployments, these tasks can be outsourced to &lt;a href="https://github.com/PaloAltoNetworks/prisma-cloud-compute-operator" rel="noopener noreferrer"&gt;Prisma Cloud Compute operator&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In today's video I am going to demonstrate how to use operator to deploy Prisma Cloud Compute console:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/owX81zax5OI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;As always, throw any questions in comments. Cheers!&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Import Existing Resources in Terraform | Prisma Cloud Compute</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Sat, 11 Dec 2021 00:35:54 +0000</pubDate>
      <link>https://dev.to/secure_daily/import-existing-resources-in-terraform-prisma-cloud-compute-37h1</link>
      <guid>https://dev.to/secure_daily/import-existing-resources-in-terraform-prisma-cloud-compute-37h1</guid>
      <description>&lt;p&gt;In this video I am showing how to use import and output workflow in order to take obtain source code for Terraform resources that are tricky to create "by hand".&lt;/p&gt;

&lt;p&gt;As in the previous vide, the focus is on Prisma Cloud Compute provider, however this workflow can be used with other Terraform providers too.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/kQa1JZOVjoo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This method works great, and have been proven to work especially well in situations were resources are easy to initially create in UI, but hard using HCL.&lt;/p&gt;

&lt;p&gt;As always, let me know if you have any questions, or feedback in comments!&lt;/p&gt;




&lt;p&gt;Reference&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terraform import - &lt;a href="https://www.terraform.io/docs/cli/import/index.html" rel="noopener noreferrer"&gt;https://www.terraform.io/docs/cli/import/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Terraform show - &lt;a href="https://www.terraform.io/docs/cli/commands/show.html" rel="noopener noreferrer"&gt;https://www.terraform.io/docs/cli/commands/show.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>terraform</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Starting with Terraform Provider | Prisma Cloud Compute</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Wed, 08 Dec 2021 22:02:49 +0000</pubDate>
      <link>https://dev.to/secure_daily/terraform-provider-for-prisma-cloud-compute-17im</link>
      <guid>https://dev.to/secure_daily/terraform-provider-for-prisma-cloud-compute-17im</guid>
      <description>&lt;p&gt;Automating your security is crucial, especially for companies operating in the cloud! I have recently made a video tutorial on how to use Terraform provider for Prisma Cloud Compute. &lt;/p&gt;

&lt;p&gt;It would help anyone using Palo Alto Network's security platform to start building automation around their security practices.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/9R3XWnl4EPs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I will include code snippets from this tutorial below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;creds.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"console_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://192.168.64.2:32677"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;main.tf&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;prismacloudcompute&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PaloAltoNetworks/prismacloudcompute"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"prismacloudcompute"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;config_file&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"creds.json"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"prismacloudcompute_collection"&lt;/span&gt; &lt;span class="s2"&gt;"node_alpine"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"node-alpine-collection"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Collection for Node images based on Alpine"&lt;/span&gt;
  &lt;span class="nx"&gt;color&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"#68A063"&lt;/span&gt;
  &lt;span class="nx"&gt;application_ids&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;code_repositories&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;images&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node:17-alpine3.12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"*/node:17-alpine3.12"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;labels&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;namespaces&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"prismacloudcompute_ci_image_vulnerability_policy"&lt;/span&gt; &lt;span class="s2"&gt;"ruleset"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;prismacloudcompute_collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node_alpine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;collections&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;prismacloudcompute_collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node_alpine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;disabled&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="nx"&gt;effect&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alert, block"&lt;/span&gt;
    &lt;span class="nx"&gt;grace_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${prismacloudcompute_collection.node_alpine.name}-ci-policy"&lt;/span&gt;
    &lt;span class="nx"&gt;notes&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CI policy for ${prismacloudcompute_collection.node_alpine.name}"&lt;/span&gt;
    &lt;span class="nx"&gt;only_fixed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="nx"&gt;verbose&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

    &lt;span class="nx"&gt;alert_threshold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;block_threshold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;cve_rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ignore ansi-regex"&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ignore"&lt;/span&gt;
      &lt;span class="nx"&gt;id&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CVE-2021-3807"&lt;/span&gt;

      &lt;span class="nx"&gt;expiration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;date&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2022-01-06T06:00:00Z"&lt;/span&gt;
        &lt;span class="nx"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;cve_rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ignore busybox"&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ignore"&lt;/span&gt;
      &lt;span class="nx"&gt;id&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CVE-2021-28831"&lt;/span&gt;

      &lt;span class="nx"&gt;expiration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;date&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2022-01-06T06:00:00Z"&lt;/span&gt;
        &lt;span class="nx"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;collections&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"All"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;disabled&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="nx"&gt;effect&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alert, block"&lt;/span&gt;
    &lt;span class="nx"&gt;grace_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;
    &lt;span class="nx"&gt;notes&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Default policy for CI scans"&lt;/span&gt;
    &lt;span class="nx"&gt;only_fixed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="nx"&gt;verbose&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

    &lt;span class="nx"&gt;alert_threshold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;block_threshold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&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;



</description>
      <category>security</category>
      <category>terraform</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Cross-platform C/C++ Development with Conan</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Sat, 13 Mar 2021 17:52:44 +0000</pubDate>
      <link>https://dev.to/secure_daily/cross-platform-c-c-development-with-conan-2276</link>
      <guid>https://dev.to/secure_daily/cross-platform-c-c-development-with-conan-2276</guid>
      <description>&lt;p&gt;Conan is an open source and multi-platform package manager to create and share native binaries (mostly C and C++). It is written in Python and supports Windows, Linux, and Mac.&lt;/p&gt;

&lt;p&gt;Besides managing dependencies, conan simplifies development process by integrating with various build tools. I touched on its most basic usage in tandem with cmake in my previous blog-post titled &lt;a href="https://dev.to/aakatev/building-http-service-in-c-using-modern-tools-14af"&gt;"Building HTTP Service in C++"&lt;/a&gt;. However, that post aimed primary towards Mac and Linux users, and developers using Windows platform were left aside.&lt;/p&gt;

&lt;p&gt;Today, let's see how we can use conan to manage cross-platform development.&lt;/p&gt;

&lt;p&gt;Let's start by creating a conanfile. Instead of using plaintext file, like in the HTTP service post, we use a Python script. Conan has ability to work with both types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;conanfile.py&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;conans&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConanFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CMake&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ConanFile&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_app&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unlicensed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Artem Akatev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;compiler&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;build_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shared&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fPIC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="n"&gt;default_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shared&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fPIC&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;generators&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cmake&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;boost/1.75.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;config_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Windows&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fPIC&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cmake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CMake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cmake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;src&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cmake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two important directives in the file are &lt;code&gt;generators&lt;/code&gt; and &lt;code&gt;requires&lt;/code&gt;. The first one contains a list of build tools, and the second a list of all dependencies. Both lists are comma delimited.&lt;/p&gt;

&lt;p&gt;The build section (Python function) contains cmake configuration. The cmake is set to expect &lt;code&gt;CMakeLists.txt&lt;/code&gt; file in src folder, so let's create the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;src/CMakeLists.txt&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;cmake_minimum_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;VERSION 2.8.12&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;my_app&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;add_definitions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"-std=c++11"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conanbuildinfo.cmake&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;conan_basic_setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;my_app main.cc&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;target_link_libraries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;my_app &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONAN_LIBS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need some application to compile. I will "steal" &lt;a href="https://www.boost.org/doc/libs/1_75_0/libs/beast/example/http/client/sync/http_client_sync.cpp" rel="noopener noreferrer"&gt;an example of HTTP client&lt;/a&gt; from Boost Beast.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;boost/beast/core.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;boost/beast/http.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;boost/beast/version.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;boost/asio/connect.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;boost/asio/ip/tcp.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;cstdlib&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;beast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// from &amp;lt;boost/beast.hpp&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// from &amp;lt;boost/beast/http.hpp&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// from &amp;lt;boost/asio.hpp&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;tcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// from &amp;lt;boost/asio/ip/tcp.hpp&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// Performs an HTTP GET and prints the response&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&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="c1"&gt;// Check command line arguments.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cerr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
                &lt;span class="s"&gt;"Usage: http-client-sync &amp;lt;host&amp;gt; &amp;lt;port&amp;gt; &amp;lt;target&amp;gt; [&amp;lt;HTTP version: 1.0 or 1.1(default)&amp;gt;]&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
                &lt;span class="s"&gt;"Example:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
                &lt;span class="s"&gt;"    http-client-sync www.example.com 80 /&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
                &lt;span class="s"&gt;"    http-client-sync www.example.com 80 / 1.0&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// The io_context is required for all I/O&lt;/span&gt;
        &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;io_context&lt;/span&gt; &lt;span class="n"&gt;ioc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// These objects perform our I/O&lt;/span&gt;
        &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;resolver&lt;/span&gt; &lt;span class="nf"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tcp_stream&lt;/span&gt; &lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Look up the domain name&lt;/span&gt;
        &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Make the connection on the IP address we get from a lookup&lt;/span&gt;
        &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Set up an HTTP GET request message&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string_body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;verb&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BOOST_BEAST_VERSION_STRING&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Send the HTTP request to the remote host&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// This buffer is used for reading and must be persisted&lt;/span&gt;
        &lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;flat_buffer&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Declare a container to hold the response&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dynamic_body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Receive the HTTP response&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Write the message to standard out&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Gracefully close the socket&lt;/span&gt;
        &lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error_code&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;shutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;shutdown_both&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// not_connected happens sometimes&lt;/span&gt;
        &lt;span class="c1"&gt;// so don't bother reporting it.&lt;/span&gt;
        &lt;span class="c1"&gt;//&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;errc&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;not_connected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;beast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;system_error&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// If we get here then the connection is closed gracefully&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cerr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;what&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&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;p&gt;Next, open a terminal window in the project's root directory (same as the directory containing &lt;code&gt;conanfile.py&lt;/code&gt;), and follow these steps to build and run the application:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install build dependencies&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;conan &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--install-folder&lt;/span&gt; build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Build binary&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;conan build &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--build-folder&lt;/span&gt; build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run your application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mac and Linux&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./build/bin/my_app google.com 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Windows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build\bin\my_app.exe google.com 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cpp</category>
      <category>conan</category>
      <category>beginners</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Implement HTTPS using Sockets and OpenSSL</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Sun, 07 Feb 2021 20:55:00 +0000</pubDate>
      <link>https://dev.to/secure_daily/implement-https-using-sockets-and-openssl-40pp</link>
      <guid>https://dev.to/secure_daily/implement-https-using-sockets-and-openssl-40pp</guid>
      <description>&lt;h2&gt;
  
  
  The Internet Protocol Stack
&lt;/h2&gt;

&lt;p&gt;Most developers are familiar with visualizing the Internet stack as a layered cake. Each layer aims to abstract away the complexity of the lower layer. There are two main conceptual models: OSI and TCP/IP. Despite using different concepts for layering, the models closely resemble each other.&lt;/p&gt;

&lt;p&gt;Both models built around the encapsulation method. The main idea is logically separate functions in the network are abstracted from their underlying structures by inclusion or information hiding within higher level objects.&lt;/p&gt;

&lt;p&gt;Each layer builds a protocol data unit (PDU) by adding a header containing control information to the data, referred as service data unit (SDU), from the layer above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz2usr2en145c2pebtjxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz2usr2en145c2pebtjxf.png" alt="Encapsulation in OSI/TCPIP" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result of encapsulation is that each lower layer provides a service to the layer or layers above it. At the same time, each layer communicates with its corresponding layer on the receiving end.&lt;/p&gt;

&lt;p&gt;One of the most widely used protocols residing on the top level is HTTP.  It is a protocol which allows the fetching of various kinds of resources. It is the foundation of any data exchange on the Internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hypertext Transfer Protocol (HTTP)
&lt;/h2&gt;

&lt;p&gt;HTTP is designed to be simple, and human readable (HTTP/2 is an exception). It uses client-server architecture.  When a client wants to communicate with a server it first creates a TCP connection, and then send a message in HTTP format.&lt;/p&gt;

&lt;p&gt;It can be something as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET / HTTP/1.1
Connection: close
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The usual response can look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/html

Hello world!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sockets
&lt;/h2&gt;

&lt;p&gt;For the actual implementation we need some programming primitives to abstract transport layer, TCP protocol. In modern operating systems such an abstractions is provided by the sockets.&lt;/p&gt;

&lt;p&gt;A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to.&lt;/p&gt;

&lt;p&gt;The following examples will use Ruby, but all modern programming languages have some library providing access to the underlying operating system sockets.&lt;/p&gt;

&lt;p&gt;Look at the the simple HTTP client making a request to &lt;a href="http://google.com" rel="noopener noreferrer"&gt;http://google.com&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"socket"&lt;/span&gt;

&lt;span class="n"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TCPSocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"www.google.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;

&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"GET / HTTP/1.0&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gets&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Transport Layer Security (TLS)
&lt;/h2&gt;

&lt;p&gt;The obvious issue with HTTP, it's not only human readable, but the data is transferred as a plaintext. It makes it impossible to use the protocol to exchange any sensitive data. To solve this issue, the modern Internet stack introduces TLS.&lt;/p&gt;

&lt;p&gt;The primary goal of the TLS protocol is to provide privacy and data integrity between two communicating applications. The protocol is composed of two layers: the TLS Record Protocol and the TLS Handshake Protocol.&lt;/p&gt;

&lt;p&gt;One advantage of TLS is that it is application protocol independent. Higher-level protocols can layer on top of the TLS protocol transparently. In the Internet stack is resides between TCP and HTTP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqnmx9kyrnbasw3ehjdvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqnmx9kyrnbasw3ehjdvn.png" alt="HTTP vs HTTPS" width="650" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenSSL
&lt;/h2&gt;

&lt;p&gt;The actual implementation of the TLS is really complex. It is not a human readable protocol, and &lt;a href="https://tls.ulfheim.net/" rel="noopener noreferrer"&gt;the data is transferred as bytes&lt;/a&gt;. The extensive use of cryptography makes it even harder to grok.&lt;/p&gt;

&lt;p&gt;OpenSSL is a robust, commercial-grade, and full-featured toolkit for the TLS protocols. It is also a general use cryptographic library. OpenSSL is widely used by web servers, including Nginx and HAProxy, and operating systems, including many Linux distributions. OpenSSL derivatives, like BoringSSL and LibreSSL power even greater number of systems and applications, like OsX, Android, Chromium, and many more.&lt;/p&gt;

&lt;p&gt;OpenSSL module for Ruby provides a wrapper for C API, and can be used to implement a simple HTTPS client making a request to &lt;a href="https://google.com" rel="noopener noreferrer"&gt;https://google.com&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"socket"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"openssl"&lt;/span&gt;

&lt;span class="n"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TCPSocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"www.google.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSLContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;secure_socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSLSocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;

&lt;span class="n"&gt;secure_socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;
&lt;span class="n"&gt;secure_socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"GET / HTTP/1.0&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;secure_socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secure_socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gets&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;secure_socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>tutorial</category>
      <category>todayilearned</category>
      <category>ruby</category>
      <category>webdev</category>
    </item>
    <item>
      <title>C++ Pointer to Function</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Wed, 27 Jan 2021 01:15:57 +0000</pubDate>
      <link>https://dev.to/secure_daily/c-pointer-to-function-7d0</link>
      <guid>https://dev.to/secure_daily/c-pointer-to-function-7d0</guid>
      <description>&lt;p&gt;Hey guys! I haven't written anything in a while, and this post will be very brief too. That said, I think you can greatly benefit from it, especially if you regularly have to deal with C/C++ (and even more likely if you learned C++ in school together with OOP).&lt;/p&gt;

&lt;p&gt;Anyhow, I will show you a paraphrased snipped from Google's crypto library BoringSSL. It is a great example of using a pointer to function.&lt;/p&gt;

&lt;p&gt;Here it is!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tool_func_t&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Tool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;tool_func_t&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;info_func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"You selected info"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;help_func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"You selected help"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt; &lt;span class="n"&gt;kTools&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info_func&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"help"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help_func&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;tool_func_t&lt;/span&gt; &lt;span class="nf"&gt;find_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kTools&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"You didn't povide any arguments"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;tool_func_t&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"You can either get info, or ask for help!"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;p&gt;The key step is &lt;code&gt;typedef&lt;/code&gt; declaration which defines the function's signature (in this example takes no arguments and returns void). After that, you have great flexibility in working with functions having this signature.&lt;/p&gt;

&lt;p&gt;Of course, you can read more about it on &lt;a href="https://www.learncpp.com/cpp-tutorial/function-pointers/" rel="noopener noreferrer"&gt;www.learncpp.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>todayilearned</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building HTTP Service in C++ (Using Modern Tools)</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Sat, 05 Dec 2020 21:50:12 +0000</pubDate>
      <link>https://dev.to/secure_daily/building-http-service-in-c-using-modern-tools-14af</link>
      <guid>https://dev.to/secure_daily/building-http-service-in-c-using-modern-tools-14af</guid>
      <description>&lt;p&gt;Today I will show you how to build an HTTP service in C++ using modern tools. The point of this article is to show how easy (or hard) it is to setup an environment for cross-platform C++ development, and package the binary in one of the modern distribution formats, container. &lt;/p&gt;

&lt;p&gt;First, a disclaimer: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am not a professional C++ developers, and any opinions shared in this tutorial should not be treated as absolute truth!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That said, since I am not profession C++ developer, this tutorial is suitable for "everyone-and-their-mother". The shell commands shown should work in most recent versions of Linux and OSX. Windows users can find themselves making some extra research, but overall the tools used are cross-platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;First things first, install the following tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cmake.org/" rel="noopener noreferrer"&gt;CMake&lt;/a&gt; - system designed to build cross-platform software.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://conan.io/" rel="noopener noreferrer"&gt;Conan&lt;/a&gt; - C/C++ package manager.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gnu.org/software/make/" rel="noopener noreferrer"&gt;Make&lt;/a&gt; - tool controlling the generation of executables.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; - set of tools for OS-level virtualization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are we building?
&lt;/h2&gt;

&lt;p&gt;The HTTP service and is mostly based on &lt;a href="https://github.com/boostorg/beast/tree/develop/example/http/server/small" rel="noopener noreferrer"&gt;this particular example&lt;/a&gt; from Boost Beast library. I modified it, replacing plaintext responses with json, and adding Boost Log library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up development tools
&lt;/h2&gt;

&lt;p&gt;Start by creating a &lt;code&gt;src&lt;/code&gt; directory in the root of your project, and putting &lt;a href="https://gist.githubusercontent.com/hi-artem/07e896d5d7b43d1cf63cf58e8665524b/raw/73d3148603c16e0505af52071b7658e6eda967b4/main.cpp" rel="noopener noreferrer"&gt;this C++ file&lt;/a&gt; inside:&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="nb"&gt;mkdir &lt;/span&gt;src
curl &lt;span class="nt"&gt;-o&lt;/span&gt; src/main.cpp https://gist.githubusercontent.com/hi-artem/07e896d5d7b43d1cf63cf58e8665524b/raw/73d3148603c16e0505af52071b7658e6eda967b4/main.cpp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although Boost is one of the well supported libraries, I always struggle manually installing it on my development machine. This is where Conan comes into play. For people familiar with Node, think of Conan as NPM or Yarn for C/C++.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;conanfile.txt&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[requires]&lt;/span&gt;
&lt;span class="err"&gt;boost/1.74.0&lt;/span&gt;

&lt;span class="nn"&gt;[generators]&lt;/span&gt;
&lt;span class="err"&gt;cmake&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, configure CMake to let it know about location of the C++ source file, and enable Conan integration. It can be done by creating &lt;code&gt;CMakeLists.txt&lt;/code&gt; looking like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;cmake_minimum_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;VERSION 3.10&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;http-service VERSION 0.0.1&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;CMAKE_CXX_STANDARD 14&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conanbuildinfo.cmake&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;conan_basic_setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nb"&gt;add_executable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;http-service src/main.cpp&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;target_link_libraries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;http-service &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CONAN_LIBS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building executable
&lt;/h2&gt;

&lt;p&gt;This is all you need to build and run the project locally! The following shell script contains all the required build commands:&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="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# remove all build folder if exists&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; build

&lt;span class="c"&gt;# create new build folder&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;build

&lt;span class="c"&gt;# install dependencies&lt;/span&gt;
conan &lt;span class="nb"&gt;install&lt;/span&gt; ..

&lt;span class="c"&gt;# generate build files&lt;/span&gt;
cmake ..

&lt;span class="c"&gt;# generate executable&lt;/span&gt;
make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once build succeded the service can be started by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./build/bin/http-service 0.0.0.0 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like:&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="o"&gt;[&lt;/span&gt;2020-12-05 13:17:27.928789] &lt;span class="o"&gt;[&lt;/span&gt;0x000000011670fdc0] &lt;span class="o"&gt;[&lt;/span&gt;info]    Service is listening on 0.0.0.0:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;curl&lt;/code&gt; or web browser, to test that service is running. For example:&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;-i&lt;/span&gt; 0.0.0.0:8000/api/status

&lt;span class="c"&gt;## Should return something similar to:&lt;/span&gt;
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 60

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;:&lt;span class="s2"&gt;"OK"&lt;/span&gt;,&lt;span class="s2"&gt;"request_count"&lt;/span&gt;:&lt;span class="s2"&gt;"1"&lt;/span&gt;,&lt;span class="s2"&gt;"timestamp"&lt;/span&gt;:&lt;span class="s2"&gt;"1607196274"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Containerizing service
&lt;/h2&gt;

&lt;p&gt;The previous steps configured development environment, however modern stacks require application to be packaged as container so it can be run by one of the orchestrators, like Kubernetes or Nomad.&lt;/p&gt;

&lt;p&gt;Since we are using Docker to containerize the service, let's start by creating &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create image with all required build tools&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ubuntu:18.04&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-tools&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;  build-essential &lt;span class="se"&gt;\
&lt;/span&gt;  cmake &lt;span class="se"&gt;\
&lt;/span&gt;  python3-pip &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;pip3 &lt;span class="nb"&gt;install &lt;/span&gt;conan


&lt;span class="c"&gt;# Build binary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-tools&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/service&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/service/build&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;conan &lt;span class="nb"&gt;install&lt;/span&gt; ..
&lt;span class="k"&gt;RUN &lt;/span&gt;cmake ..
&lt;span class="k"&gt;RUN &lt;/span&gt;make


&lt;span class="c"&gt;# Copy binary to fresh ubuntu image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ubuntu:18.04&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;runner&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;groupadd &lt;span class="nt"&gt;-r&lt;/span&gt; ubuntu &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; useradd &lt;span class="nt"&gt;--no-log-init&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ubuntu ubuntu
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; ubuntu:ubuntu&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/service/build/bin/http-service /usr/bin/http-service&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "http-service", "0.0.0.0", "8080" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The image is created using multi-stage build process: first, creating the image with all required tools to build the service; second, build the service; finally, copy the executable in fresh ubuntu image. The process is run as non-root user to avoid privileges escalation.&lt;/p&gt;

&lt;p&gt;The last thing before the image build, create &lt;code&gt;.dockerignore&lt;/code&gt; file, which serves similar purpose as &lt;code&gt;.gitignore&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build
.vscode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let's build the image. For folks no familiar with Docker, this commands will build and run the HTTP service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; http-service &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 http-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As previously, use &lt;code&gt;curl&lt;/code&gt; or web browser to test that service is running:&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;-i&lt;/span&gt; localhost:8000/api/status

&lt;span class="c"&gt;## Should return something similar to:&lt;/span&gt;
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 60

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;:&lt;span class="s2"&gt;"OK"&lt;/span&gt;,&lt;span class="s2"&gt;"request_count"&lt;/span&gt;:&lt;span class="s2"&gt;"1"&lt;/span&gt;,&lt;span class="s2"&gt;"timestamp"&lt;/span&gt;:&lt;span class="s2"&gt;"1607196274"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the image can be tagged and pushed in a Docker registry, from where it can be pulled by a container orchestrator.&lt;/p&gt;




&lt;p&gt;The purposes of this article was to reduce frustration associated with setting environment for C++ development. I hope you were able to follow. If not, the source code is available at &lt;a href="https://github.com/hi-artem/http-service" rel="noopener noreferrer"&gt;&lt;code&gt;github.com/hi-artem/http-service&lt;/code&gt;&lt;/a&gt;. Let me know in comments if you have any questions. &lt;/p&gt;

</description>
      <category>cpp</category>
      <category>tutorial</category>
      <category>todayilearned</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Cyptography for Beginners</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Sat, 24 Oct 2020 19:40:35 +0000</pubDate>
      <link>https://dev.to/secure_daily/cyptography-for-beginners-1el7</link>
      <guid>https://dev.to/secure_daily/cyptography-for-beginners-1el7</guid>
      <description>&lt;h2&gt;
  
  
  Glossary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cryptography&lt;/strong&gt; - the practice and study of techniques for secure communication in the presence of third parties. Also known as crypto and cryptology.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cipher&lt;/strong&gt; - an algorithm for performing encryption or decryption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plaintext&lt;/strong&gt; - unencrypted message or information. Also known as cleartext.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ciphertext&lt;/strong&gt; - encrypted message or information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption&lt;/strong&gt; - a process of encoding messages or information in a form that only authorized parties can read it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decryption&lt;/strong&gt; - a process of converting messages or information from ciphertext to plaintext.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Random Number Generator (RNG)&lt;/strong&gt; - a device designed to generate a sequence of numbers that lacks any pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key&lt;/strong&gt; - a parameter that determines the functional output of the cryptographic cipher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hash Function&lt;/strong&gt; - a one-way cryptographic function considered practically impossible to invert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Digest&lt;/strong&gt; - the output of the hash function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symmetric Algorithm&lt;/strong&gt; - an algorithm the uses the same cryptographic key for both encryption and decryption. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asymmetric Algorithm&lt;/strong&gt; - an algorithm the uses different cryptographic key for both encryption and decryption. Also known as public-key algorithms.&lt;/p&gt;




&lt;h2&gt;
  
  
  Symmetric Ciphers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmti4n72t6k03a26cjkkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmti4n72t6k03a26cjkkg.png" alt="Alt Text" width="690" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two types of symmetric encryption algorithms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Block  Cipher&lt;/strong&gt; - operates on fixed-length groups of bits, called blocks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stream  Cipher&lt;/strong&gt; - operates on stream of bits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Block Ciphers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Data Encryption Standard (DES)
&lt;/h3&gt;

&lt;p&gt;In modern cryptography, DES was the first standardized cipher for securing electronic communications. Due to the processing power of modern computers, DES is not used anymore as it is considered weak. It can be used in variations as 2-key or 3-key 3DES.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Encryption Standard (AES)
&lt;/h3&gt;

&lt;p&gt;This is the standard set by the US National Institute of Standards and Technology in 2001 for the encryption of electronic data. It supersedes DES which had been in use since 1977. AES has various forms, depending on the key length. They are abbreviated as AES-128, AES-192 and AES-256 where the last number is the key length in bits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Stream Ciphers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rivest Cipher 4 (RC4)
&lt;/h3&gt;

&lt;p&gt;RC4 stream chipher has been used in various protocols including Wired Equivalent Privacy (WEP) and Wi-Fi Protected Access (WPA) as well as in Transport Layer Security (TLS). However, due to some vulnerabilities discovered in 2015, it usage started to decline. RFC 7465 prohibits the use of RC4 in all versions of TLS.&lt;/p&gt;




&lt;h2&gt;
  
  
  Asymmetric Ciphers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fccworjqwdr8tqfqm1iuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fccworjqwdr8tqfqm1iuv.png" alt="Alt Text" width="735" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stream and block terms are not usually used with asymmetric ciphers. That said, public-key encryption also encrypts blocks of data. For example, RSA where block sizes are based on the key size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Asymmetric Ciphers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rivest–Shamir–Adleman (RSA)
&lt;/h3&gt;

&lt;p&gt;One of the oldest and most widely used asymmetric algorithms. It is based on the fact that if you multiply two giant prime numbers it is almost impossible to derive the original primes from the result. In fact, there is a &lt;a href="https://eprint.iacr.org/2010/006.pdf" rel="noopener noreferrer"&gt;published research&lt;/a&gt; claiming that it would take around 1500 years of computing time to crack 768 bit RSA key!&lt;/p&gt;

&lt;h3&gt;
  
  
  Elliptic Curve Cryptography (ECC)
&lt;/h3&gt;

&lt;p&gt;Like RSA, ECC works on the principle of irreversibility. In ECC, a number symbolizing a point on the curve is multiplied by another number and gives another point on the curve. Now, to crack this puzzle, you must figure out the new point on the curve. The mathematics of ECC is built in such a way that it’s virtually impossible to find out the new point, even if you know the original point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symmetric vs. Asymmetric Ciphers
&lt;/h2&gt;

&lt;p&gt;In short, this comparison is more about the cost of an elementary operation (encryption and decryption) than anything else. It would be prohibitively expensive to do asymmetric encryption for large amounts of data. Symmetric keys give you cheap computation but the problem of a shared secret. Public keys give you expensive computation but easily shared information needed to communicate securely.&lt;/p&gt;

&lt;p&gt;The effect usage of these algorithms come from creating another layer of abstraction. In other words, a researcher will have to build a system using these ciphers as primitives.&lt;/p&gt;

&lt;p&gt;For example, the following hybrid approach makes sense:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key encryption&lt;/strong&gt; - use public key cryptography to encrypt a symmetric key generated on the fly. It is expensive operation, but you only do it once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data encryption&lt;/strong&gt; - use the symmetric key to encrypt and decrypt the actual data. It is a much cheaper operation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hash Algorithms
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqr9mgguauoif18d5bzdi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqr9mgguauoif18d5bzdi.jpg" alt="Alt Text" width="667" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These algorithms are commonly used to verify information integrity or store some types of sensitive data, like passwords. Why passwords? Because the same hash function will always yield the same hash for the same input. Therefore any attempted password can be hashed and the result compared against the saved hash to verify an authentication attempt. &lt;/p&gt;

&lt;p&gt;Another memorable concept involving cryptographic hash functions is hash-based message authentication code (HMAC). It is a type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key. HMACs are used to simultaneously verify both the data integrity and the authenticity of a message. &lt;/p&gt;

&lt;h2&gt;
  
  
  Common Hash Algorithms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  MD5 Message-Digest Algorithm (MD5)
&lt;/h3&gt;

&lt;p&gt;MD5 was released in 1992 and was also built as a successor to MD4, which was successor to MD2. MD5 isn't as fast as MD4 but it is considered to be more secure than the previous MDx implementations. Although it is true, MD5 usage should be avoided in any capacity, as previous research has demonstrated, it should be considered cryptographically broken and unsuitable for further use. It can still be used as non-cryptographic hashing algorithm.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Secure Hash Algorithms (SHA)
&lt;/h3&gt;

&lt;p&gt;It is a a family of cryptographic hash functions published by the National Institute of Standards and Technology (NIST) as a US Federal Information Processing Standard (FIPS), and includes the following algorithms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SHA-1&lt;/strong&gt; - developed in 1993, and widely used in security applications and protocols, including SSL/TLS, PGP, SSH, IPsec, and S/MIME. SHA-1 produces a 160-bit digest and has a block size of 512 bits. Although SHA-1 is still widely used, cryptanalysts in 2005 were able to find vulnerabilities on the algorithm that detrimentally compromised its security. These vulnerabilities came in the form of an algorithm that speedily finds collisions with different inputs, meaning that two distinct inputs map to the same digest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SHA-2&lt;/strong&gt; - published in 2001, it consists of two hash functions known as SHA-256 and SHA-512, using 32- and 64-bit words, respectively. There are additional truncated versions of these hash functions, known as SHA-224, SHA-384, SHA-512/224, and SHA-512/256. SHA-2 produces 224 or 256-sized digests and has block sizes that contain 1024 bits, or 512 bits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SHA-3&lt;/strong&gt; - the latest member of the SHA family of standards, released in 2015. SHA-3 is a subset of the broader cryptographic primitive family Keccak and internally varies greatly from SHA-1 and SHA-2. Although SHA-3 is a better algorithm, NIST does not currently plan to withdraw SHA-2 or remove it from the revised Secure Hash Standard.&lt;/p&gt;

</description>
      <category>cryptography</category>
      <category>beginners</category>
      <category>todayilearned</category>
      <category>security</category>
    </item>
    <item>
      <title>[Learn Hugo] Develop, Stage and Prod Configurations</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Wed, 07 Oct 2020 21:56:43 +0000</pubDate>
      <link>https://dev.to/secure_daily/learn-hugo-develop-stage-and-prod-configurations-2k8d</link>
      <guid>https://dev.to/secure_daily/learn-hugo-develop-stage-and-prod-configurations-2k8d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Welcome back!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;In the previous tutorials we talked about the differences between &lt;a href="https://dev.to/aakatev/hugo-getting-started-with-static-websites-3pbb"&gt;dynamic and static websites&lt;/a&gt;, introduced Hugo, and its typical &lt;a href="https://dev.to/aakatev/learn-hugo-project-structure-14bp"&gt;project structure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today we will talk about something really important - managing configurations for multiple environments. Yes, we are jumping right into this topic without talking about the layouts and templates! Why? Well, at some point you want your website to be available on the World Wide Web. Which means you will have to put it on a hosting. Depending on the hosting provider, there could be numerous things that should be configured differently compare to the computer you develop on.&lt;/p&gt;

&lt;p&gt;Instead of thinking about the deployment last, when the website already have grown big, why don't we establish some great practices straight away?&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Environments
&lt;/h2&gt;

&lt;p&gt;For a short time, I want to pause talking about Hugo, and cover the concept of having separate environments.&lt;/p&gt;

&lt;p&gt;Typical software development workflow consists of more than one environment to make development cycles of a software application smoother and hassle free. The model usually consists of development, staging and production environments. Multiple environments suppose to help developers of the application at various phases, such as development, testing and releases.&lt;/p&gt;

&lt;p&gt;For different projects, these terms can mean different things. For a hobby website the development environment is on the developer computer, while for the bigger projects it is distributed between multiple servers. It is common for staging and production to be identical, with the main difference being a presence of the real user data. &lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Configurations in Hugo
&lt;/h2&gt;

&lt;p&gt;Getting back to Hugo, and let's jump right into coding! I will continue working on the &lt;code&gt;hello-world&lt;/code&gt; project from the previous tutorials. You can create a new project with &lt;code&gt;hugo create site&lt;/code&gt; command, since we won't really reuse any of the existing code.&lt;/p&gt;

&lt;p&gt;First thing, let's add (or create if started a new project) the following to &lt;code&gt;layouts/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; 
      &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; 
      &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ .Title }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; 
      &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; 
      &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha2/css/bootstrap.min.css"&lt;/span&gt; 
      &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha384-DhY6onE6f3zzKbjUPRc2hOzGAdEf4/Dz+WJwBvEYL/lkkIsI3ihufq9hk9K4lVoK"&lt;/span&gt; 
      &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex text-center text-white bg-dark"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 1.5em;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container w-100 pt-5 mt-5 mx-auto flex-column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to {{ .Title }}!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      The website is served at {{ .Site.BaseURL }}
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you feel lost looking at all the &lt;code&gt;{{ ... }}&lt;/code&gt; it is totally  fine. It is called templating. We  will cover it in great details in the coming posts. For now just think of it as a way to variablize a piece of HTML. &lt;/p&gt;

&lt;p&gt;Start Hugo development server (&lt;code&gt;hugo server&lt;/code&gt;), and navigate to &lt;code&gt;http://localhost:1313&lt;/code&gt;. You should see the following: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbrlccnqjy36qpmqrc1xk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbrlccnqjy36qpmqrc1xk.png" alt="Alt Text" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you open the &lt;code&gt;config.toml&lt;/code&gt; it becomes clear where the &lt;code&gt;My New Hugo Site&lt;/code&gt; part is coming from. There is also &lt;code&gt;baseURL&lt;/code&gt; property which let you set the domain name for the website. This one can be confusing. When you use the development server the &lt;code&gt;baseURL&lt;/code&gt; property gets partially overwritten. Read more about it &lt;a href="https://discourse.gohugo.io/t/confusion-with-baseurl/12125/3" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By using the configuration files, you can easily manage Hugo project in various stages of the development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development, Staging and Production
&lt;/h2&gt;

&lt;p&gt;Let's look at some real world example. Suppose a website have three environments: development, on a local machine; staging, on Github Pages; and production, on Netlify. How would the configuration for this particular website look? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftjyi2uiqh5tcpnz98ly0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftjyi2uiqh5tcpnz98ly0.png" alt="Alt Text" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, the only way to tell is to create such a website! This is not a tutorial on how to deploy a website to Netlify or Github Pages, so excuse me rushing through some of the steps. The point I want to make here is how easy it is to manage configuration with Hugo out of the box.&lt;/p&gt;

&lt;p&gt;First, let's look at the development config, &lt;strong&gt;config.toml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;baseURL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;
&lt;span class="py"&gt;languageCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"en-us"&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Development Environment"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy.&lt;/p&gt;

&lt;p&gt;Move on to staging. I will create a GitHub repository, and called it &lt;code&gt;learn-hugo&lt;/code&gt;. You are free to call it however you want. My GitHub account name is &lt;code&gt;aakatev&lt;/code&gt;, so the address for my staging website is &lt;code&gt;https://aakatev.github.io/learn-hugo/&lt;/code&gt;. The usual schema is &lt;code&gt;https://&amp;lt;username&amp;gt;.github.io/&amp;lt;repo-name&amp;gt;/&lt;/code&gt;. GitHub Pages serves files from &lt;code&gt;docs&lt;/code&gt; directory, so we should take it into account.&lt;/p&gt;

&lt;p&gt;Considering all this, here is my &lt;strong&gt;config-stage.toml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;baseURL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://aakatev.github.io/learn-hugo/"&lt;/span&gt;
&lt;span class="py"&gt;languageCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"en-us"&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Staging Environment"&lt;/span&gt;
&lt;span class="py"&gt;publishDir&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docs"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to deploy our staging version, the website has to be built locally, and pushed on GitHub. &lt;/p&gt;

&lt;p&gt;Before this moment, we have always been using the default configuration file. Hugo knows about &lt;code&gt;config.toml&lt;/code&gt;. However, now that the name is different, we have to provide &lt;code&gt;--config&lt;/code&gt; flag in order to tell Hugo which config to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hugo &lt;span class="nt"&gt;--config&lt;/span&gt; config-stage.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the website is pushed into the repo, it will automatically be deployed to GitHub Pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl1itbqa1pjcwa7ci0czq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl1itbqa1pjcwa7ci0czq.png" alt="Alt Text" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, our production environment. Netlify comes with CI/CD for static websites by default. Connect your existing GitHub repository, and provide minimum configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqwfdcculsa9up1kr237s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqwfdcculsa9up1kr237s.png" alt="Alt Text" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The default app name generated by Netlify is pretty random. You can always change it, but in my case I decided to leave it as is - &lt;code&gt;dazzling-curran-c212c7&lt;/code&gt;. The website domain name can be derived as &lt;code&gt;&amp;lt;netlify-app-name&amp;gt;.netlify.app&lt;/code&gt;, and here is the &lt;strong&gt;config-prod.toml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;baseURL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://dazzling-curran-c212c7.netlify.app/"&lt;/span&gt;
&lt;span class="py"&gt;languageCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"en-us"&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Production Environment"&lt;/span&gt;
&lt;span class="py"&gt;publishDir&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"public"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once deployed, the production version should look like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fewaofdk24sf84hc3l9ft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fewaofdk24sf84hc3l9ft.png" alt="Alt Text" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Round Up
&lt;/h2&gt;

&lt;p&gt;Again, this example was more for illustration purposes rather than actual tutorial. That said, in case you do want to try  it out yourself, the complete code is on my &lt;a href="https://github.com/aakatev/learn-hugo" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One last thing before I let you go. Although we used configuration files for this project, Hugo allows developers to separate configs by directories.&lt;/p&gt;

&lt;p&gt;For example, the config directory can have the following layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── config
│   ├── _default
│   │   ├── config.toml
│   ├── production
│   │   ├── config.toml
│   │   └── extra.toml
│   └── staging
│       ├── config.toml
│       └── extra.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note, the &lt;code&gt;_default&lt;/code&gt; sub-directory. In Hugo, it is a special name that is pretty self explanatory. This directory will be used in case no &lt;code&gt;--configDir&lt;/code&gt; flags is provided.&lt;/p&gt;

&lt;p&gt;That's it for today! Hopefully, you learned something new. Next time we will talk about Hugo layouts and templates. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay tuned!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>jamstack</category>
      <category>tutorial</category>
      <category>netlify</category>
    </item>
  </channel>
</rss>
