<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://homeostasis.scs.carleton.ca/wiki/index.php?action=history&amp;feed=atom&amp;title=DistOS_2021F_Experience_2</id>
	<title>DistOS 2021F Experience 2 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://homeostasis.scs.carleton.ca/wiki/index.php?action=history&amp;feed=atom&amp;title=DistOS_2021F_Experience_2"/>
	<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;action=history"/>
	<updated>2026-06-02T22:36:14Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23558&amp;oldid=prev</id>
		<title>Housedhorse: Clarify question 3</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23558&amp;oldid=prev"/>
		<updated>2021-11-29T17:08:48Z</updated>

		<summary type="html">&lt;p&gt;Clarify question 3&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:08, 29 November 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l132&quot;&gt;Line 132:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 132:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Printerfacts is now a CRUD app that supports creating, reading, updating, and deleting facts from the Cassandra database. In particular, we now support the following endpoints:&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Printerfacts is now a CRUD app that supports creating, reading, updating, and deleting facts from the Cassandra database. In particular, we now support the following endpoints:&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;GET&lt;/del&gt;&amp;lt;/code&amp;gt; &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/fact&lt;/del&gt;: Get a random fact from the database as a JSON object&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;GET &lt;/ins&gt;&amp;lt;code&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;10.96.0.201/fact&lt;/ins&gt;&amp;lt;/code&amp;gt;: Get a random fact from the database as a JSON object&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;code&lt;/del&gt;&amp;gt;GET&amp;lt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/&lt;/del&gt;code&amp;gt; /fact/keys: Get a list of all fact keys in the database as a JSON object&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;GET &amp;lt;code&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;10.96.0.201&lt;/ins&gt;/fact/keys&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/code&amp;gt;&lt;/ins&gt;: Get a list of all fact keys in the database as a JSON object&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;code&lt;/del&gt;&amp;gt;GET&amp;lt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/&lt;/del&gt;code&amp;gt; /fact/&amp;lt;key&amp;gt;: Get the fact with the key &amp;lt;key&amp;gt; in the database as a JSON object&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;GET &amp;lt;code&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;10.96.0.201&lt;/ins&gt;/fact/&amp;lt;key&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;/code&lt;/ins&gt;&amp;gt;: Get the fact with the key &amp;lt;key&amp;gt; in the database as a JSON object&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;POST&lt;/del&gt;&amp;lt;/code&amp;gt; &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/fact&lt;/del&gt;: Create a new fact where the request body is a JSON object of the form &amp;lt;code&amp;gt;{ &amp;amp;quot;fact&amp;amp;quot;: &amp;amp;quot;Fact Here&amp;amp;quot;, &amp;amp;quot;kind&amp;amp;quot;: &amp;amp;quot;Kind of fact (e.g. Cat fact)&amp;amp;quot; }&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;POST &lt;/ins&gt;&amp;lt;code&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;10.96.0.201/fact&lt;/ins&gt;&amp;lt;/code&amp;gt;: Create a new fact where the request body is a JSON object of the form &amp;lt;code&amp;gt;{ &amp;amp;quot;fact&amp;amp;quot;: &amp;amp;quot;Fact Here&amp;amp;quot;, &amp;amp;quot;kind&amp;amp;quot;: &amp;amp;quot;Kind of fact (e.g. Cat fact)&amp;amp;quot; }&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;code&lt;/del&gt;&amp;gt;PUT&amp;lt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/&lt;/del&gt;code&amp;gt; /fact/&amp;lt;key&amp;gt;: Modify the fact with key &amp;lt;key&amp;gt; in the database where the request body is a JSON object of the form &amp;lt;code&amp;gt;{ &amp;amp;quot;fact&amp;amp;quot;: &amp;amp;quot;Fact Here&amp;amp;quot;, &amp;amp;quot;kind&amp;amp;quot;: &amp;amp;quot;Kind of fact (e.g.  Cat fact)&amp;amp;quot; }&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;PUT &amp;lt;code&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;10.96.0.201&lt;/ins&gt;/fact/&amp;lt;key&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;/code&lt;/ins&gt;&amp;gt;: Modify the fact with key &amp;lt;key&amp;gt; in the database where the request body is a JSON object of the form &amp;lt;code&amp;gt;{ &amp;amp;quot;fact&amp;amp;quot;: &amp;amp;quot;Fact Here&amp;amp;quot;, &amp;amp;quot;kind&amp;amp;quot;: &amp;amp;quot;Kind of fact (e.g.  Cat fact)&amp;amp;quot; }&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;code&lt;/del&gt;&amp;gt;DELETE&amp;lt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/&lt;/del&gt;code&amp;gt; /fact/&amp;lt;key&amp;gt;: Delete the fact with key &amp;lt;key&amp;gt; from the database&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;DELETE &amp;lt;code&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;10.96.0.201&lt;/ins&gt;/fact/&amp;lt;key&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&amp;lt;/code&lt;/ins&gt;&amp;gt;: Delete the fact with key &amp;lt;key&amp;gt; from the database&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;p&amp;gt;Try out each of the printerfacts endpoints. Note that you can specify the HTTP request type using &amp;lt;code&amp;gt;curl -X &amp;amp;lt;type&amp;amp;gt;&amp;lt;/code&amp;gt; (for example, &amp;lt;code&amp;gt;curl -X POST&amp;lt;/code&amp;gt; to send a POST request). You can send a JSON body as a payload by using &amp;lt;code&amp;gt;curl -H &amp;#039;Content-type: application/json&amp;#039; -d &amp;#039;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;#039;&amp;lt;/code&amp;gt; where you replace the &amp;lt;code&amp;gt;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;lt;/code&amp;gt; part with your JSON object.&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;p&amp;gt;Try out each of the printerfacts endpoints. Note that you can specify the HTTP request type using &amp;lt;code&amp;gt;curl -X &amp;amp;lt;type&amp;amp;gt;&amp;lt;/code&amp;gt; (for example, &amp;lt;code&amp;gt;curl -X POST&amp;lt;/code&amp;gt; to send a POST request). You can send a JSON body as a payload by using &amp;lt;code&amp;gt;curl -H &amp;#039;Content-type: application/json&amp;#039; -d &amp;#039;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;#039;&amp;lt;/code&amp;gt; where you replace the &amp;lt;code&amp;gt;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;lt;/code&amp;gt; part with your JSON object.&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Housedhorse</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23557&amp;oldid=prev</id>
		<title>Housedhorse: Add optional part to question 3</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23557&amp;oldid=prev"/>
		<updated>2021-11-27T16:42:59Z</updated>

		<summary type="html">&lt;p&gt;Add optional part to question 3&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:42, 27 November 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l139&quot;&gt;Line 139:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 139:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt; /fact/&amp;lt;key&amp;gt;: Delete the fact with key &amp;lt;key&amp;gt; from the database&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt; /fact/&amp;lt;key&amp;gt;: Delete the fact with key &amp;lt;key&amp;gt; from the database&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;p&amp;gt;Try out each of the printerfacts endpoints. Note that you can specify the HTTP request type using &amp;lt;code&amp;gt;curl -X &amp;amp;lt;type&amp;amp;gt;&amp;lt;/code&amp;gt; (for example, &amp;lt;code&amp;gt;curl -X POST&amp;lt;/code&amp;gt; to send a POST request). You can send a JSON body as a payload by using &amp;lt;code&amp;gt;curl -H &#039;Content-type: application/json&#039; -d &#039;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&#039;&amp;lt;/code&amp;gt; where you replace the &amp;lt;code&amp;gt;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;lt;/code&amp;gt; part with your JSON object.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;p&amp;gt;Try out each of the printerfacts endpoints. Note that you can specify the HTTP request type using &amp;lt;code&amp;gt;curl -X &amp;amp;lt;type&amp;amp;gt;&amp;lt;/code&amp;gt; (for example, &amp;lt;code&amp;gt;curl -X POST&amp;lt;/code&amp;gt; to send a POST request). You can send a JSON body as a payload by using &amp;lt;code&amp;gt;curl -H &#039;Content-type: application/json&#039; -d &#039;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&#039;&amp;lt;/code&amp;gt; where you replace the &amp;lt;code&amp;gt;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;lt;/code&amp;gt; part with your JSON object.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/p&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;p&amp;gt;Optional: Try restarting the Cassandra pods using &amp;lt;code&amp;gt;kubectl rollout restart statefulset cassandra&amp;lt;/code&amp;gt;. While the pods are restarting, watch the output of &amp;lt;code&amp;gt;kubectl get pods --watch&amp;lt;/code&amp;gt; and try making requests to the printerfacts service at the same time. Do you notice any downtime?&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Let’s use Cilium and Hubble to observe dataflows between our Cassandra database and the printerfacts service. To do this, run the following Hubble command: &amp;lt;code&amp;gt;hubble observe    --label component=server --label component=printerfacts -f&amp;lt;/code&amp;gt;. Make a few requests to the printerfacts service, exercising various API endpoints. Try and make sense of some of the network traffic you observe.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Let’s use Cilium and Hubble to observe dataflows between our Cassandra database and the printerfacts service. To do this, run the following Hubble command: &amp;lt;code&amp;gt;hubble observe    --label component=server --label component=printerfacts -f&amp;lt;/code&amp;gt;. Make a few requests to the printerfacts service, exercising various API endpoints. Try and make sense of some of the network traffic you observe.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;In an effort to secure your cluster, you decide to employ a Cilium network policy that locks down the printerfacts service. First, download the example security policy by running &amp;lt;code&amp;gt;wget https://homeostasis.scs.carleton.ca/~will/printerfacts-policy.yml&amp;lt;/code&amp;gt;, then run &amp;lt;code&amp;gt;kubectl apply -f policy.yml&amp;lt;/code&amp;gt; to apply it. The example policy allows GET requests to &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fact&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fact/keys&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;/fact/&amp;amp;lt;key&amp;amp;gt;&amp;lt;/code&amp;gt;. Examine the policy file and make sure you understand how it works.&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;In an effort to secure your cluster, you decide to employ a Cilium network policy that locks down the printerfacts service. First, download the example security policy by running &amp;lt;code&amp;gt;wget https://homeostasis.scs.carleton.ca/~will/printerfacts-policy.yml&amp;lt;/code&amp;gt;, then run &amp;lt;code&amp;gt;kubectl apply -f policy.yml&amp;lt;/code&amp;gt; to apply it. The example policy allows GET requests to &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fact&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fact/keys&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;/fact/&amp;amp;lt;key&amp;amp;gt;&amp;lt;/code&amp;gt;. Examine the policy file and make sure you understand how it works.&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Housedhorse</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23542&amp;oldid=prev</id>
		<title>Housedhorse: /* Part 1: Multi-Node Kubernetes, Cilium, and Cassandra (Easy) */</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23542&amp;oldid=prev"/>
		<updated>2021-11-27T01:14:54Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Part 1: Multi-Node Kubernetes, Cilium, and Cassandra (Easy)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 01:14, 27 November 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l119&quot;&gt;Line 119:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 119:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Thanks the Cilium CNI, your Kubernetes &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;clusters &lt;/del&gt;has been outfitted with new eBPF superpowers. In particular, Cilium installs a series of eBPF programs into your (VM’s) kernel which can be used to monitor traffic between containers, pods, and nodes, as well as enforce L4–L7 security policy. To test out your new superpowers, run &amp;lt;code&amp;gt;cilium hubble port-forward&amp;amp;amp;&amp;lt;/code&amp;gt; followed by &amp;lt;code&amp;gt;hubble observe&amp;lt;/code&amp;gt;. What is all that output? Can you make sense of any of it?&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Thanks the Cilium CNI, your Kubernetes &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;cluster &lt;/ins&gt;has been outfitted with new eBPF superpowers. In particular, Cilium installs a series of eBPF programs into your (VM’s) kernel which can be used to monitor traffic between containers, pods, and nodes, as well as enforce L4–L7 security policy. To test out your new superpowers, run &amp;lt;code&amp;gt;cilium hubble port-forward&amp;amp;amp;&amp;lt;/code&amp;gt; followed by &amp;lt;code&amp;gt;hubble observe&amp;lt;/code&amp;gt;. What is all that output? Can you make sense of any of it?&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;ul&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;Hint 1: Try checking &amp;lt;code&amp;gt;hubble --help&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;hubble observe --help&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;li&amp;gt;Hint 1: Try checking &amp;lt;code&amp;gt;hubble --help&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;hubble observe --help&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Housedhorse</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23541&amp;oldid=prev</id>
		<title>Housedhorse: Touch experience 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=DistOS_2021F_Experience_2&amp;diff=23541&amp;oldid=prev"/>
		<updated>2021-11-27T01:08:30Z</updated>

		<summary type="html">&lt;p&gt;Touch experience 2&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
In this experience, you will be playing with a multi-node Kubernetes cluster simulated using &amp;lt;code&amp;gt;minikube&amp;lt;/code&amp;gt;, running the [https://docs.cilium.io/en/v1.10/ Cilium CNI], a replicated [https://cassandra.apache.org/doc/latest/ Apache Cassandra] database and an updated version of our beloved “printerfacts” service that consumes facts stored in the Cassandra database. As usual, you may wish to consult the relevant documentation if you get stuck. Links to documentation will be provided along with hints later on in this document.&lt;br /&gt;
&lt;br /&gt;
With the exception of Part 2, completing this experience shouldn’t take more than a couple of hours. Feel free to collaborate with other students if you get stuck. However, &amp;#039;&amp;#039;&amp;#039;you must acknowledge any collaboration&amp;#039;&amp;#039;&amp;#039;. Additionally, &amp;#039;&amp;#039;&amp;#039;copying and pasting or simply “changing up” each other’s answers will be treated as an academic integrity violation&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Submissions ==&lt;br /&gt;
&lt;br /&gt;
Your experience report should be submitted as a PDF file on Brightspace, written in &amp;#039;&amp;#039;&amp;#039;paragraph form&amp;#039;&amp;#039;&amp;#039;. Code snippets or screenshots are allowed to augment your prose but are not required. We will post a submission link on Brightspace within the next few days.&lt;br /&gt;
&lt;br /&gt;
The official due date for the experience report is December 10th (the last day of class), but we will continue to accept submissions up until the date of the final exam if you need extra time.&lt;br /&gt;
&lt;br /&gt;
== Receiving Your Grade ==&lt;br /&gt;
&lt;br /&gt;
This experience is broken up into three parts:&lt;br /&gt;
&lt;br /&gt;
# A series of easy tasks designed to get you familiar Cilium, Cassandra, and a multi-node K8s cluster.&lt;br /&gt;
# A harder challenge that involves programming a client to interact with the Cassandra database and writing a custom Cilium security policy to lock down your cluster.&lt;br /&gt;
# An opportunity to reflect on this experience and make connections to overall themes in the course.&lt;br /&gt;
&lt;br /&gt;
Students are expected to complete Part 1 and Part 3 to get a grade of at most a B+. &amp;#039;&amp;#039;&amp;#039;Part 2 is optional&amp;#039;&amp;#039;&amp;#039;, but must be completed to receive a grade of A- or higher. Marks will be deducted for insufficient explanations or answers that demonstrate a lack of effort. By this logic, you should have a fairly clear idea of what grade you will receive when you submit this experience, based on how much effort you put in.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Your Environment ==&lt;br /&gt;
&lt;br /&gt;
For this experience, a new VM image has been provided for you. It has a larger disk size, more RAM, and a batteries-included installation of the [https://github.com/cilium/cilium-cli Cilium] and [https://github.com/cilium/hubble Hubble] CLI. First, &amp;#039;&amp;#039;&amp;#039;delete your old instance&amp;#039;&amp;#039;&amp;#039; using the OpenStack web console, then create a new one. You can follow the [https://homeostasis.scs.carleton.ca/wiki/index.php/DistOS_2021F:_Using_Openstack same instructions as before], except replace the &amp;lt;code&amp;gt;COMP4000-studentvm-v1&amp;lt;/code&amp;gt; image with &amp;lt;code&amp;gt;COMP4000-studentvm-v2&amp;lt;/code&amp;gt;. When selecting your flavour, make sure you pick the flavour with &amp;#039;&amp;#039;&amp;#039;16GiB of disk space and 8GB of RAM&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Once your VM is set up, SSH into it using your preferred SSH client. You should probably be working with at least 2 terminals for the rest of this experience. After SSHing into your instance, run the following command to spin up a multi-node k8s cluster: &amp;lt;code&amp;gt;minikube start -n3 --cni=cilium&amp;lt;/code&amp;gt;. This might take a few minutes to run to completion.&lt;br /&gt;
&lt;br /&gt;
Verify your cluster has started correctly using &amp;lt;code&amp;gt;minikube status&amp;lt;/code&amp;gt;. You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;minikube&lt;br /&gt;
type: Control Plane&lt;br /&gt;
host: Running&lt;br /&gt;
kubelet: Running&lt;br /&gt;
apiserver: Running&lt;br /&gt;
kubeconfig: Configured&lt;br /&gt;
&lt;br /&gt;
minikube-m02&lt;br /&gt;
type: Worker&lt;br /&gt;
host: Running&lt;br /&gt;
kubelet: Running&lt;br /&gt;
&lt;br /&gt;
minikube-m03&lt;br /&gt;
type: Worker&lt;br /&gt;
host: Running&lt;br /&gt;
kubelet: Running&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Cilium and Hubble ===&lt;br /&gt;
&lt;br /&gt;
Once your cluster is running, you can configure the cluster to use Cilium and Hubble. Due to some minikube and Cilium quirks, we need to uninstall the default version of Cilium installed by minikube and reinstall it using the Cilium CLI. You can do so with the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cilium uninstall &amp;amp;amp;&amp;amp;amp; cilium install &amp;amp;amp;&amp;amp;amp; cilium hubble enable&amp;lt;/pre&amp;gt;&lt;br /&gt;
This may take a few minutes to run to completion.&lt;br /&gt;
&lt;br /&gt;
You can run the command &amp;lt;code&amp;gt;cilium status&amp;lt;/code&amp;gt; to check the status of your Cilium installation. Once everything has installed correctly, you should see something like the following when running &amp;lt;code&amp;gt;cilium status&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;student@alpine:~$ cilium status&lt;br /&gt;
    /¯¯\&lt;br /&gt;
 /¯¯\__/¯¯\    Cilium:         OK&lt;br /&gt;
 \__/¯¯\__/    Operator:       OK&lt;br /&gt;
 /¯¯\__/¯¯\    Hubble:         OK&lt;br /&gt;
 \__/¯¯\__/    ClusterMesh:    disabled&lt;br /&gt;
    \__/&lt;br /&gt;
&lt;br /&gt;
Deployment        cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1&lt;br /&gt;
Deployment        hubble-relay       Desired: 1, Ready: 1/1, Available: 1/1&lt;br /&gt;
DaemonSet         cilium             Desired: 3, Ready: 3/3, Available: 3/3&lt;br /&gt;
Containers:       cilium             Running: 3&lt;br /&gt;
                  cilium-operator    Running: 1&lt;br /&gt;
                  hubble-relay       Running: 1&lt;br /&gt;
Cluster Pods:     2/2 managed by Cilium&lt;br /&gt;
Image versions    cilium             quay.io/cilium/cilium:v1.10.5: 3&lt;br /&gt;
                  cilium-operator    quay.io/cilium/operator-generic:v1.10.5: 1&lt;br /&gt;
                  hubble-relay       quay.io/cilium/hubble-relay:v1.10.5: 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Cassandra ===&lt;br /&gt;
&lt;br /&gt;
We will be using the &amp;lt;code&amp;gt;helm&amp;lt;/code&amp;gt; package manger to install Cassandra in our k8s cluster. To do so, run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://homeostasis.scs.carleton.ca/~will/cassandra.yml&lt;br /&gt;
helm repo add bitnami https://charts.bitnami.com/bitnami&lt;br /&gt;
helm install cassandra bitnami/cassandra -f cassandra.yml&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can verify the status of your Cassandra installation using &amp;lt;code&amp;gt;kubectl get pods --watch&amp;lt;/code&amp;gt;. Wait until both &amp;lt;code&amp;gt;cassandra-0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cassandra-1&amp;lt;/code&amp;gt; show &amp;lt;code&amp;gt;1/1&amp;lt;/code&amp;gt; under &amp;lt;code&amp;gt;READY&amp;lt;/code&amp;gt;. This might take a few minutes. The output should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;student@alpine:~$ kubectl get pods&lt;br /&gt;
NAME                      READY   STATUS    RESTARTS      AGE&lt;br /&gt;
cassandra-0               1/1     Running   0             4m2s&lt;br /&gt;
cassandra-1               1/1     Running   0             2m8s&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Printerfacts ===&lt;br /&gt;
&lt;br /&gt;
The printerfacts service from last experience has received an upgrade to work with our new Cassandra database. First, run the migrations (provided as a batch job) to initialize the Cassandra database and populate it with some facts about printers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://homeostasis.scs.carleton.ca/~will/migrations.yml&lt;br /&gt;
kubectl apply -f migrations.yml&amp;lt;/pre&amp;gt;&lt;br /&gt;
After applying the migrations, you’re ready to deploy the printerfacts service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://homeostasis.scs.carleton.ca/~will/deploy.yml&lt;br /&gt;
kubectl apply -f deploy.yml&amp;lt;/pre&amp;gt;&lt;br /&gt;
Verify that printerfacts has been correctly deployed with &amp;lt;code&amp;gt;kubectl get pods&amp;lt;/code&amp;gt;. You should see something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;student@alpine:~$ kubectl get pods&lt;br /&gt;
NAME                      READY   STATUS    RESTARTS      AGE&lt;br /&gt;
cassandra-0               1/1     Running   0             31m&lt;br /&gt;
cassandra-1               1/1     Running   0             30m&lt;br /&gt;
server-85f9f4465b-9vhn9   1/1     Running   0             38m&lt;br /&gt;
server-85f9f4465b-b7s2n   1/1     Running   0             38m&lt;br /&gt;
server-85f9f4465b-bvgqs   1/1     Running   0             38m&lt;br /&gt;
server-85f9f4465b-bwf42   1/1     Running   0             38m&lt;br /&gt;
server-85f9f4465b-gn5sm   1/1     Running   0             38m&amp;lt;/pre&amp;gt;&lt;br /&gt;
Finally, run &amp;lt;code&amp;gt;minikube tunnel&amp;lt;/code&amp;gt; in a separate terminal to set up port forwarding for our &amp;lt;code&amp;gt;LoadBalancer&amp;lt;/code&amp;gt; API objects. This will enable you to interact with printerfacts from your VM, rather than needing to spin up a client pod like last time.&lt;br /&gt;
&lt;br /&gt;
Verify that it worked correctly by running &amp;lt;code&amp;gt;curl 10.96.0.201&amp;lt;/code&amp;gt; (this is the IP you will use to talk to printerfacts). Note that depending on your specific configuration, you may need to SSH into minikube using &amp;lt;code&amp;gt;minikube ssh&amp;lt;/code&amp;gt; before you can access the load balancer service. If your curl command hangs forever, this may be the issue.&lt;br /&gt;
&lt;br /&gt;
= Tasks =&lt;br /&gt;
&lt;br /&gt;
== Part 1: Multi-Node Kubernetes, Cilium, and Cassandra (Easy) ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions for each of the following numbered tasks. Make an effort to answer the accompanying questions, but more importantly please note down all of your observations and describe what you did for each task. You should also feel free to write down whatever questions you may have about a given task.&lt;br /&gt;
&lt;br /&gt;
To achieve the best possible grade in this section, you must demonstrate that you have made an effort to understand the results of each task. (Note that an effort does not strictly mean a full understanding; it is okay to have questions!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Thanks the Cilium CNI, your Kubernetes clusters has been outfitted with new eBPF superpowers. In particular, Cilium installs a series of eBPF programs into your (VM’s) kernel which can be used to monitor traffic between containers, pods, and nodes, as well as enforce L4–L7 security policy. To test out your new superpowers, run &amp;lt;code&amp;gt;cilium hubble port-forward&amp;amp;amp;&amp;lt;/code&amp;gt; followed by &amp;lt;code&amp;gt;hubble observe&amp;lt;/code&amp;gt;. What is all that output? Can you make sense of any of it?&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Hint 1: Try checking &amp;lt;code&amp;gt;hubble --help&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;hubble observe --help&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Hint 2: [https://docs.cilium.io/en/v1.10/gettingstarted/hubble/ Check out the Hubble docs]&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Unlike last time, our cluster consists of three nodes rather than just one. Try running &amp;lt;code&amp;gt;curl 10.96.0.201&amp;lt;/code&amp;gt; a few times and notice that the output now includes a node name in addition to a pod name. Do you notice any patterns in the output? Compare what you see with the output from running &amp;lt;code&amp;gt;kubectl get pods -o wide&amp;lt;/code&amp;gt;. Try to come up with an explanation for the distribution of printerfacts pods over the nodes in your cluster.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Hint 1: Have a look at the &amp;lt;code&amp;gt;affinity&amp;lt;/code&amp;gt; section of &amp;lt;code&amp;gt;deploy.yml&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Hint 2: Have a look at the [https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity relevant documentation].&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Hint 3: If you still can’t get it, an educated guess will suffice.&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Printerfacts is now a CRUD app that supports creating, reading, updating, and deleting facts from the Cassandra database. In particular, we now support the following endpoints:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; /fact: Get a random fact from the database as a JSON object&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; /fact/keys: Get a list of all fact keys in the database as a JSON object&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; /fact/&amp;lt;key&amp;gt;: Get the fact with the key &amp;lt;key&amp;gt; in the database as a JSON object&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;POST&amp;lt;/code&amp;gt; /fact: Create a new fact where the request body is a JSON object of the form &amp;lt;code&amp;gt;{ &amp;amp;quot;fact&amp;amp;quot;: &amp;amp;quot;Fact Here&amp;amp;quot;, &amp;amp;quot;kind&amp;amp;quot;: &amp;amp;quot;Kind of fact (e.g. Cat fact)&amp;amp;quot; }&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;PUT&amp;lt;/code&amp;gt; /fact/&amp;lt;key&amp;gt;: Modify the fact with key &amp;lt;key&amp;gt; in the database where the request body is a JSON object of the form &amp;lt;code&amp;gt;{ &amp;amp;quot;fact&amp;amp;quot;: &amp;amp;quot;Fact Here&amp;amp;quot;, &amp;amp;quot;kind&amp;amp;quot;: &amp;amp;quot;Kind of fact (e.g.  Cat fact)&amp;amp;quot; }&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt; /fact/&amp;lt;key&amp;gt;: Delete the fact with key &amp;lt;key&amp;gt; from the database&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Try out each of the printerfacts endpoints. Note that you can specify the HTTP request type using &amp;lt;code&amp;gt;curl -X &amp;amp;lt;type&amp;amp;gt;&amp;lt;/code&amp;gt; (for example, &amp;lt;code&amp;gt;curl -X POST&amp;lt;/code&amp;gt; to send a POST request). You can send a JSON body as a payload by using &amp;lt;code&amp;gt;curl -H &amp;#039;Content-type: application/json&amp;#039; -d &amp;#039;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;#039;&amp;lt;/code&amp;gt; where you replace the &amp;lt;code&amp;gt;{&amp;amp;quot;key&amp;amp;quot;: &amp;amp;quot;value&amp;amp;quot;}&amp;lt;/code&amp;gt; part with your JSON object.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Let’s use Cilium and Hubble to observe dataflows between our Cassandra database and the printerfacts service. To do this, run the following Hubble command: &amp;lt;code&amp;gt;hubble observe    --label component=server --label component=printerfacts -f&amp;lt;/code&amp;gt;. Make a few requests to the printerfacts service, exercising various API endpoints. Try and make sense of some of the network traffic you observe.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;In an effort to secure your cluster, you decide to employ a Cilium network policy that locks down the printerfacts service. First, download the example security policy by running &amp;lt;code&amp;gt;wget https://homeostasis.scs.carleton.ca/~will/printerfacts-policy.yml&amp;lt;/code&amp;gt;, then run &amp;lt;code&amp;gt;kubectl apply -f policy.yml&amp;lt;/code&amp;gt; to apply it. The example policy allows GET requests to &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fact&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fact/keys&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;/fact/&amp;amp;lt;key&amp;amp;gt;&amp;lt;/code&amp;gt;. Examine the policy file and make sure you understand how it works.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Try out your policy by making a few valid requests followed by some invalid ones. While your policy is applied, try using Hubble to observe the HTTP traffic by running &amp;lt;code&amp;gt;hubble observe --protocol http&amp;lt;/code&amp;gt;. Optionally, try extending the policy to make some other valid routes work (e.g. PUT, POST, and DELETE requests).&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Hint: You may wish to consult the [https://docs.cilium.io/en/v1.10/gettingstarted/http/ Cilium docs]&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now that you’re familiar with printerfacts, it’s time to simulate a node failure. Since both printerfacts and Cassandra are replicated across multiple nodes in our cluster, taking one of them down should not impact either service.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Let’s first try a planned node disruption. This kind of disruption might occur when a cluster administrator wants to take a node down for maintenance, for example to perform a kernel update. Start by draining node &amp;lt;code&amp;gt;minikube-m02&amp;lt;/code&amp;gt; with the command &amp;lt;code&amp;gt;kubectl drain minikube-m02 --ignore-daemonsets&amp;lt;/code&amp;gt;. Now try interacting with the printerfacts service as before. Make note of any unusual behaviour and try to come up with a best-guess explanation.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Now you can bring your node back up using &amp;lt;code&amp;gt;kubectl uncordon minikube-m02&amp;lt;/code&amp;gt;. Once your node has been uncordoned, it should be ready for scheduling again. Try scaling up the printerfacts deployment to get some pods running on the node again.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Finally, let’s simulate a total node failure. To do this, we will kill the underlying kubelet for our node, which is running on your system as a Docker container. Use the &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; command to find the container ID that corresponds to your node, then kill it using &amp;lt;code&amp;gt;docker kill&amp;lt;/code&amp;gt;. Repeat the same experiments from before, documenting any unusual behaviour you observe.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Part 2: Interacting with Cassandra (Hard) ==&lt;br /&gt;
&lt;br /&gt;
Note that this part of the experience is only required if you wish to achieve a grade of A- or higher. You can also choose to skip one of the two questions here, but doing so will likely impact your grade.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Write a Cilium security policy that allows only SELECT and INSERT queries to the &amp;lt;code&amp;gt;pfacts.facts&amp;lt;/code&amp;gt; table in Cassandra. All other queries should be denied. Apply your policy and demonstrate how it works using a few examples queries. You may wish to consult [https://docs.cilium.io/en/v1.10/gettingstarted/cassandra/#how-to-secure-a-cassandra-database the Cilium policy docs].&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Hint: You can use this [https://homeostasis.scs.carleton.ca/~will/cassandra-policy.yml policy template] as a starting point.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Write and deploy your own containerized application as a replicated deployment to interact with the Cassandra database in some interesting way. You can choose to extend the printerfacts schema or come up with your own schema, depending on your preference. Be sure to explain how your application deals with Cassandra’s consistency model in a replicated cluster. In order to achieve points for this question, you &amp;#039;&amp;#039;&amp;#039;must&amp;#039;&amp;#039;&amp;#039; make some meaningful modifications to the database. Just consuming the existing data in a new way is not sufficient.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Hint 1: Cassandra allows the client to choose their consistency level when making queries. Hint 2: Cassandra queries are made in CQL, a NoSQL query language that is similar to but not totally compatible with SQL. Hint 3: You can spawn a &amp;lt;code&amp;gt;cqlsh&amp;lt;/code&amp;gt; session to issue test CQL queries like &amp;lt;code&amp;gt;kubectl exec -it cassandra-0 -- cqlsh&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Part 3: Reflection ==&lt;br /&gt;
&lt;br /&gt;
Summarize your experience with multi-node Kubernetes, Cilium, and Cassandra in a few paragraphs (both the good and the bad). What concepts do you see reflected here from the research papers we have read thus far? After having some hands on experience with a distributed system technology, have any of your opinions or initial assumptions changed? Feel free to list any other thoughts you have.&lt;br /&gt;
&lt;br /&gt;
= Acknowledgements =&lt;br /&gt;
&lt;br /&gt;
The idea for the printerfacts API comes from Christine Dodrill’s [https://christine.website/blog/dev-printerfact-2021-04-17 wonderful blog post].&lt;/div&gt;</summary>
		<author><name>Housedhorse</name></author>
	</entry>
</feed>