<?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: Alex Yaroslavsky</title>
    <description>The latest articles on DEV Community by Alex Yaroslavsky (@trexinc).</description>
    <link>https://dev.to/trexinc</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%2F430531%2Faa84bcc4-956d-4ee1-a2c6-7bd0168a3e55.jpeg</url>
      <title>DEV Community: Alex Yaroslavsky</title>
      <link>https://dev.to/trexinc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/trexinc"/>
    <language>en</language>
    <item>
      <title>How to prevent a potential remote code execution via SnakeYAML deserialization</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Thu, 05 Aug 2021 08:02:53 +0000</pubDate>
      <link>https://dev.to/trexinc/how-to-prevent-a-potential-remote-code-execution-via-snakeyaml-deserialization-b60</link>
      <guid>https://dev.to/trexinc/how-to-prevent-a-potential-remote-code-execution-via-snakeyaml-deserialization-b60</guid>
      <description>&lt;p&gt;A popular java library for YAML parsing, SnakeYAML, has a well know vulnerability if used incorrectly to parse user generated YAMLs.&lt;/p&gt;

&lt;p&gt;You can read about the vulnerability itself here: &lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="https://swapneildash.medium.com/snakeyaml-deserilization-exploited-b4a2c5ac0858" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afill%3A88%3A88%2F0%2AirDXDm-47WxLmQo7." alt="Swapneil Kumar Dash"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://swapneildash.medium.com/snakeyaml-deserilization-exploited-b4a2c5ac0858" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;SnakeYaml Deserilization exploited | by Swapneil Kumar Dash | Medium&lt;/h2&gt;
      &lt;h3&gt;Swapneil Kumar Dash ・ &lt;time&gt;Sep 9, 2019&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fmedium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        swapneildash.Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;The solutions for this problem that I have found on the net are either incorrect or unusable in real life. So I want to share here the solution that I have come up with.&lt;/p&gt;

&lt;p&gt;It is quite simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;parseYamlSafe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Constructor&lt;/span&gt; &lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Yaml&lt;/span&gt; &lt;span class="n"&gt;yamlParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Yaml&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SafeConstructor&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;// the following line throws an exception&lt;/span&gt;
    &lt;span class="c1"&gt;// if constructors for non standard java types exist in yaml&lt;/span&gt;
    &lt;span class="n"&gt;yamlParser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;//if we got here, the YAML is safe to parse.&lt;/span&gt;
    &lt;span class="n"&gt;yamlParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Yaml&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;yamlParser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>yaml</category>
      <category>security</category>
      <category>rce</category>
      <category>java</category>
    </item>
    <item>
      <title>Great article about tips for a better life</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Fri, 01 Jan 2021 20:40:11 +0000</pubDate>
      <link>https://dev.to/trexinc/great-article-about-tips-for-a-better-life-29gj</link>
      <guid>https://dev.to/trexinc/great-article-about-tips-for-a-better-life-29gj</guid>
      <description>&lt;p&gt;&lt;a href="https://ideopunk.com/2020/12/22/100-tips-for-a-better-life/"&gt;Link to article&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Making Home and End keys work on Mac</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Wed, 30 Dec 2020 08:27:34 +0000</pubDate>
      <link>https://dev.to/trexinc/making-home-and-end-keys-work-on-mac-5fb</link>
      <guid>https://dev.to/trexinc/making-home-and-end-keys-work-on-mac-5fb</guid>
      <description>&lt;h1&gt;
  
  
  Fix for most applications
&lt;/h1&gt;

&lt;p&gt;Open a terminal window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/Library
mkdir KeyBindings
cd KeyBindings
pico DefaultKeyBinding.dict
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the contents of the text below to the file, press Ctrl-X to exit the editor and select Y to save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
/* Remap Home / End keys */
/* Home Button*/
"\UF729" = "moveToBeginningOfLine:"; 
/* End Button */
"\UF72B" = "moveToEndOfLine:"; 
/* Shift + Home Button */
"$\UF729" = "moveToBeginningOfLineAndModifySelection:"; 
/* Shift + End Button */
"$\UF72B" = "moveToEndOfLineAndModifySelection:"; 
/* Ctrl + Home Button */
"^\UF729" = "moveToBeginningOfDocument:"; 
/* Ctrl + End Button */
"^\UF72B" = "moveToEndOfDocument:"; 
 /* Shift + Ctrl + Home Button */
"$^\UF729" = "moveToBeginningOfDocumentAndModifySelection:";
/* Shift + Ctrl + End Button*/
"$^\UF72B" = "moveToEndOfDocumentAndModifySelection:"; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Fix for Terminal
&lt;/h1&gt;

&lt;p&gt;Open terminal and go to preferences. Select the profile you use and go to the keyboard tab. Look for the the entries with actions &lt;code&gt;\033b&lt;/code&gt; (home) and &lt;code&gt;\033f&lt;/code&gt; (end) and edit them. When you edit them, select key Home or End respectively and modifier none.&lt;/p&gt;

</description>
      <category>macintosh</category>
      <category>osx</category>
      <category>keyboard</category>
      <category>navigation</category>
    </item>
    <item>
      <title>Best explanation of Kubernetes services</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Wed, 30 Dec 2020 08:16:59 +0000</pubDate>
      <link>https://dev.to/trexinc/best-explanation-of-kubernetes-services-k4p</link>
      <guid>https://dev.to/trexinc/best-explanation-of-kubernetes-services-k4p</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/swlh/kubernetes-services-simply-visually-explained-2d84e58d70e5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ltMbsPn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/fit/c/96/96/2%2AuQsRpcGS-vOw3n69oJXNmA.jpeg" alt="Kim Wuestkamp"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/swlh/kubernetes-services-simply-visually-explained-2d84e58d70e5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Kubernetes Services simply visually explained | by Kim Wuestkamp | The Startup | Medium&lt;/h2&gt;
      &lt;h3&gt;Kim Wuestkamp ・ &lt;time&gt;Jul 19, 2020&lt;/time&gt; ・ 6 min read
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KBvj_QRD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/medium_icon-90d5232a5da2369849f285fa499c8005e750a788fdbf34f5844d5f2201aae736.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Netstat without Netstat inside Containers</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Thu, 23 Jul 2020 15:07:58 +0000</pubDate>
      <link>https://dev.to/trexinc/netstat-without-netstat-inside-containers-9ak</link>
      <guid>https://dev.to/trexinc/netstat-without-netstat-inside-containers-9ak</guid>
      <description>&lt;p&gt;A very hardcore but simple way to view open connections and ports open for listening in any Linux container. Use the following command even inside any bare bones container without netstat and such tools:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep -v "rem_address" /proc/net/tcp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The output will be something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   0: 00000000:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 6106109 1 ffff889f5ff35800 100 0 0 10 0
   1: 00000000:0C6D 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 6112091 1 ffff889ee7e96000 100 0 0 10 0
   2: 611F820A:0C6D E61E820A:A5E6 01 00000000:00000000 00:00000000 00000000     0        0 6122922 1 ffff889d2b712800 20 0 0 10 -1
   3: 611F820A:0C6D E61E820A:A5EE 01 00000000:00000000 00:00000000 00000000     0        0 6118270 1 ffff889e736e3000 20 4 21 10 -1
   4: 611F820A:1F40 F21F820A:DE3E 01 00000000:00000000 00:00000000 00000000     0        0 6119808 1 ffff889e78be7000 20 4 3 10 -1
   5: 611F820A:0C6D E61E820A:A5FC 01 00000000:00000000 00:00000000 00000000     0        0 6128773 1 ffff889e78bf2000 20 4 33 10 -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two left columns are source address and port and destination address and port in hex. The first two rows in this example correlate to listening ports (the destination is all zeros) and the rest are open connections.&lt;/p&gt;

&lt;p&gt;To get this in a bit more human readable form you can run the following command that should also work inside most containers:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep -v "rem_address" /proc/net/tcp | awk 'function hextonum(str, ret, n, i, k, c) {if (str ~ /^0[xX][0-9a-fA-F]+$/) {str = substr(str, 3);n = length(str);ret = 0;for (i = 1; i &amp;lt;= n; i++) {c = substr(str, i, 1);c = tolower(c);k = index("123456789abcdef", c);ret = ret * 16 + k}} else ret = "NOT-A-NUMBER";return ret} {y=hextonum("0x"substr($2,index($2,":")-2,2));x=hextonum("0x"substr($3,index($3,":")-2,2));for (i=5; i&amp;gt;0; i-=2) {x = x"."hextonum("0x"substr($3,i,2));y = y"."hextonum("0x"substr($2,i,2));} print y":"hextonum("0x"substr($2,index($2,":")+1,4))" "x":"hextonum("0x"substr($3,index($3,":")+1,4));}'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The output will be similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.0.0.0:8000 0.0.0.0:0
0.0.0.0:3181 0.0.0.0:0
10.130.31.97:3181 10.130.30.230:42470
10.130.31.97:3181 10.130.30.230:42478
10.130.31.97:8000 10.130.31.242:56894
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to understand how this command works - leave a comment!&lt;/p&gt;

</description>
      <category>containers</category>
      <category>docker</category>
      <category>kubernetes</category>
      <category>netstat</category>
    </item>
    <item>
      <title>Multiple AWS accounts and CLI</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Sat, 18 Jul 2020 11:54:17 +0000</pubDate>
      <link>https://dev.to/trexinc/multiple-aws-accounts-and-cli-26ih</link>
      <guid>https://dev.to/trexinc/multiple-aws-accounts-and-cli-26ih</guid>
      <description>&lt;p&gt;After following this guide you will able to easily and seamlessly switch between multiple AWS accounts and roles (with or without Okta) using the CLI.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Prerequisites:&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Check out the first article in the series for requirements and initial configuration.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/trexinc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aD94Nio6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--P5RTnJ7v--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/430531/aa84bcc4-956d-4ee1-a2c6-7bd0168a3e55.jpeg" alt="trexinc image"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/trexinc/aws-cli-with-okta-mpn" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;AWS CLI with Okta&lt;/h2&gt;
      &lt;h3&gt;Alex Yaroslavsky ・ Jul 13 ・ 2 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cli&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#okta&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;





&lt;h3&gt;
  
  
  &lt;em&gt;How To:&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;The following instructions are meant to be used in Linux or WSL, tested with Ubuntu.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Configure non Okta accounts
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure --profile profile
aws configure --profile multi-role-profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure Okta accounts
&lt;/h4&gt;

&lt;p&gt;Create a file &lt;code&gt;~/.okta-aws&lt;/code&gt; with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[okta-profile]
username = &amp;lt;username&amp;gt;
factor = OKTA
app-link = https://&amp;lt;your-company&amp;gt;.okta.com/&amp;lt;app-link&amp;gt;
base-url = &amp;lt;your-company&amp;gt;.okta.com
duration = 3600

[okta-multi-role-profile]
username = &amp;lt;username&amp;gt;
factor = OKTA
app-link = https://&amp;lt;your-company&amp;gt;.okta.com/&amp;lt;app-link&amp;gt;
base-url = &amp;lt;your-company&amp;gt;.okta.com
duration = 3600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Initialize the profiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;okta-awscli --okta-profile okta-profile --profile okta-profile
okta-awscli --okta-profile okta-multi-role-profile --profile okta-multi-role-profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure accounts with multiple roles
&lt;/h4&gt;

&lt;p&gt;Some accounts might use role switching, add similar sections to &lt;code&gt;~/.aws/credentials&lt;/code&gt; per role (notice that &lt;code&gt;source_profile&lt;/code&gt; points to a previously defined profile):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[multi-role-profile-role1]
role_arn = &amp;lt;role-arn&amp;gt;
source_profile = multi-role-profile

[okta-multi-role-profile-role1]
role_arn = &amp;lt;role-arn&amp;gt;
source_profile = okta-multi-role-profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Associate EKS clusters with profiles
&lt;/h4&gt;

&lt;p&gt;Run the following per EKS cluster that you want to have kubectl access to, &lt;code&gt;&amp;lt;profile-name&amp;gt;&lt;/code&gt; is a name of the AWS profile defined above that has permissions for this EKS cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws --profile &amp;lt;profile-name&amp;gt; eks update-kubeconfig --name &amp;lt;eks-cluster-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Create scripts for fast account switching
&lt;/h4&gt;

&lt;p&gt;The scripts switch to the relevant AWS account, point kubectl to the relevant cluster, and set a default kubectl namespace.&lt;br&gt;
Create one script file per profile, and place it in your home directory.&lt;/p&gt;

&lt;p&gt;File &lt;code&gt;okta-multi-role-profile-role1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export AWS_DEFAULT_PROFILE=okta-multi-role-profile-role1
kubectl config use-context &amp;lt;eks-cluster-arn&amp;gt;
kubectl config set-context --current --namespace=&amp;lt;namespace&amp;gt;
aws sts get-caller-identity
if [[ $PS1 != *"AWS_DEFAULT_PROFILE"* ]]; then
  PS1=\(\$AWS_DEFAULT_PROFILE\)$PS1
fi
echo "Switched to okta-multi-role-profile-role1"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Switch between accounts
&lt;/h4&gt;

&lt;p&gt;To quickly switch between accounts just do the following:&lt;br&gt;
&lt;code&gt;source &amp;lt;profile-file&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;code&gt;source okta-multi-role-profile-role1&lt;/code&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cli</category>
      <category>okta</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Spring Boot and Graceful Service Shutdown</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Sat, 18 Jul 2020 10:24:20 +0000</pubDate>
      <link>https://dev.to/trexinc/spring-boot-and-graceful-service-shutdown-549d</link>
      <guid>https://dev.to/trexinc/spring-boot-and-graceful-service-shutdown-549d</guid>
      <description>&lt;p&gt;Imagine your service running in Kubernetes, having the time of its life, and then suddenly you push a new version through the pipeline. Before starting the new version, Kubernetes needs to stop the old one. It first asks your service nicely to exit (SIGTERM), if your service doesn't respond to that it will be violently killed (SIGKILL) after several seconds. So if you want to close various resources correctly and exit gracefully, there are some steps you must take.&lt;/p&gt;

&lt;p&gt;Below is an example of a generic skeleton for a Spring Boot Service that wants to handle shutdowns gracefully.&lt;/p&gt;

&lt;p&gt;The main idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a separate thread with main application logic&lt;/li&gt;
&lt;li&gt;Wait for application closing event (called upon SIGTERM)&lt;/li&gt;
&lt;li&gt;Interrupt the main application logic thread and exit&lt;/li&gt;
&lt;li&gt;PROFIT;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; Don't forget to &lt;del&gt;eat&lt;/del&gt; destroy your Beans, for Beans that implement the AutoClosable interface this is extremely simple:&lt;br&gt;
&lt;code&gt;@Bean(destroyMethod = "close")&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>spring</category>
      <category>springboot</category>
      <category>shutdown</category>
      <category>exit</category>
    </item>
    <item>
      <title>AWS CLI with Okta</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Mon, 13 Jul 2020 20:02:59 +0000</pubDate>
      <link>https://dev.to/trexinc/aws-cli-with-okta-mpn</link>
      <guid>https://dev.to/trexinc/aws-cli-with-okta-mpn</guid>
      <description>&lt;p&gt;We will be using this solution: &lt;a href="https://github.com/jmhale/okta-awscli"&gt;https://github.com/jmhale/okta-awscli&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Prerequisites:&lt;/em&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Python3&lt;br&gt;
Windows: &lt;a href="https://www.python.org/downloads/"&gt;https://www.python.org/downloads/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS CLI V1&lt;br&gt;
Windows: &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html&lt;/a&gt;&lt;br&gt;
Mac: &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/install-macos.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/install-macos.html&lt;/a&gt;&lt;br&gt;
Linux: &lt;code&gt;pip3 install awscli --upgrade --user&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Install okta-awscli:&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;pip3 install okta-awscli&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Initial setup:&lt;/em&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create aws profiles for dev and test.&lt;br&gt;
Run the following:&lt;br&gt;
&lt;code&gt;aws configure set region us-east-1 --profile dev&lt;/code&gt;&lt;br&gt;
&lt;code&gt;aws configure set output text --profile dev&lt;/code&gt;&lt;br&gt;
&lt;code&gt;aws configure set region us-east-1 --profile test&lt;/code&gt;&lt;br&gt;
&lt;code&gt;aws configure set output text --profile test&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the following file:&lt;br&gt;
Linux: ~/.okta-aws&lt;br&gt;
Windows: %USERPROFILE%.okta-aws&lt;br&gt;
With the following contents:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[dev]&lt;br&gt;
username = &lt;br&gt;
factor = OKTA&lt;br&gt;
app-link = &amp;lt;copy link from app icon in okta&amp;gt;&lt;br&gt;
base-url = &amp;gt;your-company&amp;gt;.okta.com&lt;br&gt;
duration = 3600&lt;/p&gt;

&lt;p&gt;[test]&lt;br&gt;
username = &lt;br&gt;
factor = OKTA&lt;br&gt;
app-link = &amp;lt;copy link from app icon in okta&amp;gt;&lt;br&gt;
base-url = &amp;lt;your-company&amp;gt;.okta.com&lt;br&gt;
duration = 3600&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Login and run aws commands:&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;okta-awscli --okta-profile dev --profile dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After logging in with okta-awscli, your login is valid for an hour and you can use aws commands (using the --profile )&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Login to ECR:&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;aws --profile dev ecr get-login --registry-ids &amp;lt;your-ecr-id&amp;gt; --no-include-email&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will generate a token that you can use to login with docker to the ECR to pull images.&lt;br&gt;
It will actually output the full command you need to run, so just copy it and run.&lt;br&gt;
It will look like this:&lt;br&gt;
docker login -u AWS -p  https://&amp;lt;your-ecr-id&amp;gt;.dkr.ecr.us-east-1.amazonaws.com&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cli</category>
      <category>okta</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Spring Boot and Multiple Authentication Profiles (None, Password &amp; Okta)</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Mon, 13 Jul 2020 16:02:58 +0000</pubDate>
      <link>https://dev.to/trexinc/spring-boot-and-multiple-authentication-profiles-none-password-okta-5bce</link>
      <guid>https://dev.to/trexinc/spring-boot-and-multiple-authentication-profiles-none-password-okta-5bce</guid>
      <description>&lt;p&gt;Ahoy Spring user!&lt;/p&gt;

&lt;p&gt;Recently, I added Okta login to my application to secure the &lt;em&gt;admin&lt;/em&gt; section of the website. This is simple enough to accomplish but suddenly I felt the need to run my application locally without any authentication for testing purposes. As I couldn't find any good info on this on the web I decided to share the solution I came up with.&lt;/p&gt;

&lt;p&gt;Full source code is here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/trexinc"&gt;
        trexinc
      &lt;/a&gt; / &lt;a href="https://github.com/trexinc/spring-multi-web-security-config"&gt;
        spring-multi-web-security-config
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Spring Boot and Multiple Authentication Profiles (None, Password &amp;amp; Okta)
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h1&gt;
  
  
  &lt;strong&gt;A few quick words on setting up Okta authentication&lt;/strong&gt;
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Register for a free developer account at &lt;a href="https://developer.okta.com/"&gt;https://developer.okta.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a Spring Boot project with the following &lt;a href="https://start.spring.io/#!type=gradle-project&amp;amp;language=java&amp;amp;platformVersion=2.3.1.RELEASE&amp;amp;packaging=jar&amp;amp;jvmVersion=1.8&amp;amp;groupId=example.trexinc&amp;amp;artifactId=multi.web.security.config&amp;amp;name=multi.web.security.config&amp;amp;description=&amp;amp;packageName=example.trexinc.multi.web.security.config&amp;amp;dependencies=web,oauth2-client,thymeleaf,security"&gt;Spring Initialzer settings&lt;/a&gt;. 
Dependencies: Spring Web, Spring Security, Thymeleaf &amp;amp; OAuth2 Client.
This solution works specifically &lt;strong&gt;with&lt;/strong&gt; OAuth2 Client &lt;strong&gt;and not&lt;/strong&gt; the native Okta library.&lt;/li&gt;
&lt;li&gt;In Okta application configuration change the Login redirect URIs to:
&lt;a href="http://localhost:8080/login/oauth2/code/okta"&gt;http://localhost:8080/login/oauth2/code/okta&lt;/a&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WOpaGETf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2t28kubue3l27rx3eurs.png" alt="Okta configuration"&gt;
&lt;/li&gt;
&lt;li&gt;In your &lt;em&gt;application.properties&lt;/em&gt; configure the following:
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;And you need to define a Web Security Config to enable Okta authentication:
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Back to the actual point&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;To enable several different security profiles I came up with the following solution. We define several Web Security Configurations each with its own &lt;code&gt;@Profile("ProfileX)&lt;/code&gt; annotation, which enables this profile only when this profile is enabled in Spring.&lt;br&gt;
The code looks likes this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The relevant &lt;em&gt;applications.properties&lt;/em&gt; sections look like this (of course only the one you want to use should be enabled, and it should be enabled only at runtime in your CI/CD pipeline):&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h1&gt;
  
  
  &lt;strong&gt;What is the best way to run the code locally?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Once we have the code and know how to make it work one issue remains, what is the best way to run it locally with authentication disabled without modifying the &lt;em&gt;application.properties&lt;/em&gt; files and risking pushing those modifications to productions.&lt;/p&gt;

&lt;p&gt;Two options that I like the most:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure the relevant Spring profile in InteliJ, go to &lt;em&gt;"Edit Configurations..."&lt;/em&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G93lF42c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4zdx8tf32xorm24qvczv.png" alt="Edit Configurations..."&gt;
And set the profile as &lt;em&gt;local&lt;/em&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NlPD-6x3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b7j4z87s5754w8ucr53c.PNG" alt="Set profile"&gt;
&lt;/li&gt;
&lt;li&gt;Configure a &lt;em&gt;bootRun&lt;/em&gt; task in &lt;em&gt;build.gradle&lt;/em&gt; that will set the profile to local (unless defined otherwise in the environment):
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. Hope you found this useful. Leave comments and likes :)&lt;/p&gt;

</description>
      <category>spring</category>
      <category>springboot</category>
      <category>okta</category>
      <category>security</category>
    </item>
    <item>
      <title>Integration testing Apache Pulsar clients with Docker Compose and TestContainers</title>
      <dc:creator>Alex Yaroslavsky</dc:creator>
      <pubDate>Mon, 13 Jul 2020 05:59:40 +0000</pubDate>
      <link>https://dev.to/trexinc/integration-testing-apache-pulsar-clients-with-docker-compose-and-testcontainers-4kgn</link>
      <guid>https://dev.to/trexinc/integration-testing-apache-pulsar-clients-with-docker-compose-and-testcontainers-4kgn</guid>
      <description>&lt;p&gt;Hello, quarantined user!&lt;/p&gt;

&lt;p&gt;I would like to share with you my adventures with a complex Docker Compose testing scenario using TestContainers Java library that by pure coincidence (not really) also involves the coolest new kid on the block - Apache &lt;em&gt;"The Kafka Killer"&lt;/em&gt; Pulsar.&lt;/p&gt;

&lt;p&gt;Full source code is available at the end of the article.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Three main tools we are going to use today&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Apache Pulsar
&lt;/h3&gt;

&lt;p&gt;A distributed pub-sub messaging system with stream processing capabilities. It combines tenant isolation, seamless scaling and all the functionality of RabbitMQ and Kafka in one pretty damn badass package.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Compose
&lt;/h3&gt;

&lt;p&gt;A tool that allows you to keep multiple container configurations in a nice YAML file and to run multiple containers with one command.&lt;/p&gt;

&lt;h3&gt;
  
  
  TestContainers
&lt;/h3&gt;

&lt;p&gt;A Java library for integration testing that can spin up any containers and let your tests interact with them in an easy and convenient way.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;What are we trying to accomplish?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;We want to set up an environment with the following components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K7Y086IL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5tdmxy7lgxh4weydkw00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K7Y086IL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5tdmxy7lgxh4weydkw00.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Apache Pulsar with three tenants: &lt;em&gt;"internal"&lt;/em&gt;, &lt;em&gt;"customer1"&lt;/em&gt; &amp;amp; &lt;em&gt;"customer2"&lt;/em&gt;. All messages sent to the "customer" tenants will be routed by a Pulsar Function to a single topic in the "internal" tenant for easy centralized consumption.&lt;/li&gt;
&lt;li&gt;Two Producers that will be sending messages to tenants &lt;em&gt;"customer1"&lt;/em&gt; and &lt;em&gt;"customer2"&lt;/em&gt; respectively - topic name: &lt;em&gt;"/outbound/corona"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;A single Consumer that will be receiving all messages from both Producers from a single topic &lt;em&gt;"internal/inbound/corona"&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It might seem that creating a single compose file with all the services above should give us what we need, but, it is not the case. First, we must start the Pulsar server, wait for it to load, configure all the tenants and the Functions. Then, we should start the consumer so it will be ready to read the messages and then finally start the producers. After all the components are up and running we want to verify that the producers are sending messages and the consumer is receiving them.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Can we do it manually first?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Before trying to automate the task, let's figure out how to do it manually using only Docker Compose.&lt;/p&gt;

&lt;p&gt;We already understand that we will need several compose files and we know that all the components must be able to communicate with each other, which means that they have to be on the same network. Docker Compose allows just that. We can define a network in one compose file and then use it in another compose file by marking it there as external.&lt;/p&gt;

&lt;p&gt;Here you can see a Pulsar compose file that defines a network called &lt;em&gt;"local-pulsar-net"&lt;/em&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And here is a different compose file that uses the same network for its service:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We see above that the &lt;em&gt;"pulsar-net"&lt;/em&gt; network that is defined in this compose file is linked to an external network called &lt;em&gt;"local-pulsar-net"&lt;/em&gt;, which happens to be the network we defined in the previous compose file.&lt;/p&gt;

&lt;p&gt;Running those compose files with &lt;code&gt;docker-compose up&lt;/code&gt; will place the containers in the same network and they will be able to communicate with each other by their respective service names.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Let's automate this coronapulsar!&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;TestContainers library is quite powerful and easy to use, here is an example code snippet showing how to start a Pulsar server from a compose file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Until this point all is great, we can even create a &lt;em&gt;PulsarAdmin&lt;/em&gt; client and configure our Pulsar the way that we need. Unfortunately, starting the second compose file that references the network defined in the Pulsar compose file just fails with an exception:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ocrysPtn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p0vde06zmjnkr9sq1krf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ocrysPtn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p0vde06zmjnkr9sq1krf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happens is that TestContainers adds a random prefix to all components it loads to Docker. This is of course necessary to prevent name collisions and such when loading many different compose files. So, for example, our &lt;em&gt;"local-pulsar-net"&lt;/em&gt; is created as &lt;em&gt;"pulsarrpekn3_local-pulsar-net"&lt;/em&gt; in the run above. And the name will be different in the next one and so on…&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Let's solve this COVID-bug!&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;It seems that in order to solve our issue we need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To know the random name of the "local-pulsar-net" network as generated by TestContainers.&lt;/li&gt;
&lt;li&gt;To somehow apply this name to the existing additional compose files before loading them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fortunately, there is way to do both. Hooray!&lt;/p&gt;

&lt;p&gt;Getting the name of the network:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;To apply the network name to the remaining compose files we can use the following trick, define the network like this in the YAML files:&lt;/p&gt;

&lt;p&gt;note the last line - &lt;code&gt;name: $PULSAR_NETWORK&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This allows to pass the name of the network as an environment variable when starting the compose file, like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h1&gt;
  
  
  &lt;strong&gt;The final chapter&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;You can find the full source code that starts and configures a standalone Pulsar, then starts a Consumer, two Producers, verifies that they are all working correctly and shuts down the environment on my GitHub page: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/trexinc"&gt;
        trexinc
      &lt;/a&gt; / &lt;a href="https://github.com/trexinc/pulsar-integration-testing"&gt;
        pulsar-integration-testing
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Integration testing Apache Pulsar clients with Docker Compose and TestContainers
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Thank you for reading! Like the page and leave some comments, hope this article was useful to you.&lt;/p&gt;

&lt;p&gt;Stay healthy &amp;amp; safe!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>pulsar</category>
      <category>docker</category>
      <category>testcontainers</category>
    </item>
  </channel>
</rss>
