-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
276 lines (268 loc) · 21.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
<!doctype html>
<html class="default no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>@pennlabs/kittyhawk</title>
<meta name="description" content="Documentation for @pennlabs/kittyhawk">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/main.css">
<script async src="assets/js/search.js" id="search-script"></script>
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="assets/js/search.json" data-base=".">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</div>
<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>
<a href="index.html" class="title">@pennlabs/kittyhawk</a>
</div>
<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">All</span>
<ul class="tsd-select-list">
<li data-value="public">Public</li>
<li data-value="protected">Public/Protected</li>
<li data-value="private" class="selected">All</li>
</ul>
</div>
<input type="checkbox" id="tsd-filter-inherited" checked />
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
</div>
</div>
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
</div>
</div>
</div>
</div>
<div class="tsd-page-title">
<div class="container">
<h1>@pennlabs/kittyhawk</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<div class="tsd-panel tsd-typography">
<a href="#kittyhawk" id="kittyhawk" style="color: inherit; text-decoration: none;">
<h1>Kittyhawk</h1>
</a>
<p>Kittyhawk is the automated Kubernetes YAML generator for Penn Labs.
With Kittyhawk, you can define an application's deployment configuration in Typescript using objects called <a href="https://cdk8s.io/docs/v1.0.0-beta.3/concepts/constructs/">constructs</a>.</p>
<a href="#getting-started" id="getting-started" style="color: inherit; text-decoration: none;">
<h1>Getting Started</h1>
</a>
<p>The easiest way to get started with a Kittyhawk project is by following the following steps or by copying one of our existing products. At the end of this README, you can also see a simple example typescript file using Kittyhawk.</p>
<a href="#1-set-up-cdk8s-typescript-project" id="1-set-up-cdk8s-typescript-project" style="color: inherit; text-decoration: none;">
<h2>1. Set up CDK8s Typescript Project</h2>
</a>
<p>Create a <code>k8s</code> folder within your project. Inside the <code>k8s</code> folder, initialize a <code>cdk8s</code> typescript project. You can do that by following the official cdk8s instructions <a href="https://cdk8s.io/docs/latest/getting-started/#new-project">here</a>. </p>
<a href="#2-add-kittyhawk" id="2-add-kittyhawk" style="color: inherit; text-decoration: none;">
<h2>2. Add Kittyhawk</h2>
</a>
<p>Import the kittyhawk library (<code>yarn add @pennlabs/kittyhawk</code>) and start writing your deployment configuration in Typescript.</p>
<p>At the very top level, add to your <code>main.ts</code> file in the following format using the <code>PennLabsChart</code>. </p>
<pre><code><span style="color: #AF00DB">export</span><span style="color: #000000"> </span><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">MyChart</span><span style="color: #000000"> </span><span style="color: #0000FF">extends</span><span style="color: #000000"> </span><span style="color: #267F99">PennLabsChart</span><span style="color: #000000"> {</span>
<span style="color: #000000"> </span><span style="color: #0000FF">constructor</span><span style="color: #000000">(</span><span style="color: #001080">scope</span><span style="color: #000000">: </span><span style="color: #267F99">Construct</span><span style="color: #000000">) {</span>
<span style="color: #000000"> </span><span style="color: #0000FF">super</span><span style="color: #000000">(</span><span style="color: #001080">scope</span><span style="color: #000000">);</span>
<span style="color: #000000"> }</span>
<span style="color: #000000">}</span>
</code></pre>
<p>Within your chart, you can add various applications, cronjobs, and other configurations supported by kittyhawk, including the following custom constructs:</p>
<ul>
<li><code>ReactApplication</code></li>
<li><code>DjangoApplication</code></li>
<li><code>CronJob</code></li>
<li><code>Redis</code></li>
</ul>
<p>For more advanced custom constructs, please refer to our <a href="https://kittyhawk.pennlabs.org/">documentation</a></p>
<a href="#cron-time-generator" id="cron-time-generator" style="color: inherit; text-decoration: none;">
<h3>Cron-time-generator</h3>
</a>
<p>In many of our Penn Labs products, we use cronjobs to simplify our product tasks (e.g. loading courses, calculating office hours wait time). </p>
<p><code>cron-time-generator</code> (<a href="https://www.npmjs.com/package/cron-time-generator">npm link</a>) is a package that allows for intuitive generation of cron job time expressions. </p>
<p>It is not required to use this, but it is a dependency for kittyhawk and better practice: instead of specifying the time of a cronjob that runs every 5 minutes as <code>*/5 * * * *</code>, you can say <code>cronTime.every(5).minutes()</code>. </p>
<p>For specifics of using <code>cron-time-generator</code>, refer to the documentation on npm or our code example at the bottom of this doc.</p>
<a href="#3-incorporate-kittyhawk-into-ci" id="3-incorporate-kittyhawk-into-ci" style="color: inherit; text-decoration: none;">
<h2>3. Incorporate Kittyhawk into CI</h2>
</a>
<p>After the typescript constructs have been added and configured, the deployment yaml can be generated. </p>
<a href="#how-yaml-generation-works-command-line" id="how-yaml-generation-works-command-line" style="color: inherit; text-decoration: none;">
<h3>How yaml generation works (command line)</h3>
</a>
<blockquote>
<p><strong>Note</strong>: You should <em>NOT</em> be generating yaml manually and adding the generated yaml to the repository. Instead, it's important to add the yaml generation to the github actions or the CI you have already built. </p>
</blockquote>
<p>The following instructions are for <em>local testing purposes only</em> and if you want to understand what goes on under the hood.</p>
<p>To generate a yaml file, you must first change (<code>cd</code>) into the <code>k8s/cdk</code> directory. Then, you can generate the yaml by running <code>yarn compile && yarn synth</code>. The generated yaml file would appear in the <code>dist</code> folder (<code>RELEASE_NAME.k8s.yaml</code>). </p>
<blockquote>
<p>For yaml generation to work properly, it's required to specify the following environment variables:</p>
<ul>
<li><code>RELEASE_NAME</code>: the name of the application being deploy (set to name of repository)</li>
<li><code>GIT_SHA</code>: the sha of the latest commit</li>
</ul>
</blockquote>
<a href="#adding-kittyhawk-to-the-ci" id="adding-kittyhawk-to-the-ci" style="color: inherit; text-decoration: none;">
<h3>Adding Kittyhawk to the CI</h3>
</a>
<p>The deploy job (<code>DeployJob</code>) in <a href="https://github.com/pennlabs/infrastructure/tree/master/cdk/kraken">Kraken</a> would handle the yaml file generation process. For more information, see the <a href="https://kraken.pennlabs.org/">kraken documentation</a>.</p>
<a href="#example" id="example" style="color: inherit; text-decoration: none;">
<h2>Example</h2>
</a>
<p>A sample <code>main.ts</code> file is included below, covering the more common use cases for Penn Labs products:</p>
<pre><code><span style="color: #AF00DB">import</span><span style="color: #000000"> { </span><span style="color: #001080">Construct</span><span style="color: #000000"> } </span><span style="color: #AF00DB">from</span><span style="color: #000000"> </span><span style="color: #A31515">'constructs'</span><span style="color: #000000">;</span>
<span style="color: #AF00DB">import</span><span style="color: #000000"> { </span><span style="color: #001080">PennLabsChart</span><span style="color: #000000">, </span><span style="color: #001080">ReactApplication</span><span style="color: #000000">, </span><span style="color: #001080">DjangoApplication</span><span style="color: #000000">, </span><span style="color: #001080">RedisApplication</span><span style="color: #000000">, </span><span style="color: #001080">CronJob</span><span style="color: #000000"> } </span><span style="color: #AF00DB">from</span><span style="color: #000000"> </span><span style="color: #A31515">'@pennlabs/kittyhawk'</span><span style="color: #000000">;</span>
<span style="color: #0000FF">const</span><span style="color: #000000"> </span><span style="color: #0070C1">cronTime</span><span style="color: #000000"> = </span><span style="color: #795E26">require</span><span style="color: #000000">(</span><span style="color: #A31515">'cron-time-generator'</span><span style="color: #000000">);</span>
<span style="color: #AF00DB">export</span><span style="color: #000000"> </span><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">ExampleChart</span><span style="color: #000000"> </span><span style="color: #0000FF">extends</span><span style="color: #000000"> </span><span style="color: #267F99">PennLabsChart</span><span style="color: #000000"> {</span>
<span style="color: #000000"> </span><span style="color: #0000FF">constructor</span><span style="color: #000000">(</span><span style="color: #001080">scope</span><span style="color: #000000">: </span><span style="color: #267F99">Construct</span><span style="color: #000000">) {</span>
<span style="color: #000000"> </span><span style="color: #0000FF">super</span><span style="color: #000000">(</span><span style="color: #001080">scope</span><span style="color: #000000">);</span>
<span style="color: #000000"> </span><span style="color: #0000FF">const</span><span style="color: #000000"> </span><span style="color: #0070C1">backendImage</span><span style="color: #000000"> = </span><span style="color: #A31515">'pennlabs/example-backend'</span><span style="color: #000000">;</span>
<span style="color: #000000"> </span><span style="color: #0000FF">const</span><span style="color: #000000"> </span><span style="color: #0070C1">frontendImage</span><span style="color: #000000"> = </span><span style="color: #A31515">'pennlabs/examplefrontend'</span><span style="color: #000000">;</span>
<span style="color: #000000"> </span><span style="color: #0000FF">const</span><span style="color: #000000"> </span><span style="color: #0070C1">secret</span><span style="color: #000000"> = </span><span style="color: #A31515">'secret'</span><span style="color: #000000">;</span>
<span style="color: #000000"> </span><span style="color: #0000FF">const</span><span style="color: #000000"> </span><span style="color: #0070C1">domain</span><span style="color: #000000"> = </span><span style="color: #A31515">'domain'</span><span style="color: #000000">;</span>
<span style="color: #000000"> </span><span style="color: #0000FF">new</span><span style="color: #000000"> </span><span style="color: #795E26">RedisApplication</span><span style="color: #000000">(</span><span style="color: #0000FF">this</span><span style="color: #000000">, </span><span style="color: #A31515">'redis'</span><span style="color: #000000">, {});</span>
<span style="color: #000000"> </span><span style="color: #0000FF">new</span><span style="color: #000000"> </span><span style="color: #795E26">DjangoApplication</span><span style="color: #000000">(</span><span style="color: #0000FF">this</span><span style="color: #000000">, </span><span style="color: #A31515">'django-asgi'</span><span style="color: #000000">, {</span>
<span style="color: #000000"> </span><span style="color: #001080">deployment:</span><span style="color: #000000"> {</span>
<span style="color: #000000"> </span><span style="color: #001080">image:</span><span style="color: #000000"> </span><span style="color: #001080">backendImage</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">cmd:</span><span style="color: #000000"> [</span><span style="color: #A31515">'/usr/local/bin/asgi-run'</span><span style="color: #000000">],</span>
<span style="color: #000000"> </span><span style="color: #001080">replicas:</span><span style="color: #000000"> </span><span style="color: #098658">2</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">secret:</span><span style="color: #000000"> </span><span style="color: #001080">secret</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">env:</span><span style="color: #000000"> [</span>
<span style="color: #000000"> { </span><span style="color: #001080">name:</span><span style="color: #000000"> </span><span style="color: #A31515">'REDIS_HOST'</span><span style="color: #000000">, </span><span style="color: #001080">value:</span><span style="color: #000000"> </span><span style="color: #A31515">'redis'</span><span style="color: #000000"> },</span>
<span style="color: #000000"> ],</span>
<span style="color: #000000"> },</span>
<span style="color: #000000"> </span><span style="color: #001080">djangoSettingsModule:</span><span style="color: #000000"> </span><span style="color: #A31515">'example.settings.production'</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">domains:</span><span style="color: #000000"> [{ </span><span style="color: #001080">host:</span><span style="color: #000000"> </span><span style="color: #001080">domain</span><span style="color: #000000">, </span><span style="color: #001080">paths:</span><span style="color: #000000"> [</span><span style="color: #A31515">'/api/ws'</span><span style="color: #000000">] }],</span>
<span style="color: #000000"> });</span>
<span style="color: #000000"> </span><span style="color: #0000FF">new</span><span style="color: #000000"> </span><span style="color: #795E26">ReactApplication</span><span style="color: #000000">(</span><span style="color: #0000FF">this</span><span style="color: #000000">, </span><span style="color: #A31515">'react'</span><span style="color: #000000">, {</span>
<span style="color: #000000"> </span><span style="color: #001080">deployment:</span><span style="color: #000000"> {</span>
<span style="color: #000000"> </span><span style="color: #001080">image:</span><span style="color: #000000"> </span><span style="color: #001080">frontendImage</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">replicas:</span><span style="color: #000000"> </span><span style="color: #098658">2</span><span style="color: #000000">,</span>
<span style="color: #000000"> },</span>
<span style="color: #000000"> </span><span style="color: #001080">domain:</span><span style="color: #000000"> { </span><span style="color: #001080">host:</span><span style="color: #000000"> </span><span style="color: #001080">domain</span><span style="color: #000000">, </span><span style="color: #001080">paths:</span><span style="color: #000000"> [</span><span style="color: #A31515">'/'</span><span style="color: #000000">] },</span>
<span style="color: #000000"> </span><span style="color: #001080">portEnv:</span><span style="color: #000000"> </span><span style="color: #A31515">'80'</span><span style="color: #000000">,</span>
<span style="color: #000000"> });</span>
<span style="color: #000000"> </span><span style="color: #008000">/** Cronjobs **/</span>
<span style="color: #000000"> </span><span style="color: #0000FF">new</span><span style="color: #000000"> </span><span style="color: #795E26">CronJob</span><span style="color: #000000">(</span><span style="color: #0000FF">this</span><span style="color: #000000">, </span><span style="color: #A31515">'example-cronjob'</span><span style="color: #000000">, {</span>
<span style="color: #000000"> </span><span style="color: #001080">schedule:</span><span style="color: #000000"> </span><span style="color: #001080">cronTime</span><span style="color: #000000">.</span><span style="color: #795E26">everyDayAt</span><span style="color: #000000">(</span><span style="color: #098658">8</span><span style="color: #000000">),</span>
<span style="color: #000000"> </span><span style="color: #001080">image:</span><span style="color: #000000"> </span><span style="color: #001080">backendImage</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">secret:</span><span style="color: #000000"> </span><span style="color: #001080">secret</span><span style="color: #000000">,</span>
<span style="color: #000000"> </span><span style="color: #001080">cmd:</span><span style="color: #000000"> [</span><span style="color: #A31515">'your'</span><span style="color: #000000">, </span><span style="color: #A31515">'command'</span><span style="color: #000000">],</span>
<span style="color: #000000"> });</span>
<span style="color: #000000"> }</span>
<span style="color: #000000">}</span>
</code></pre>
</div>
</div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
<nav class="tsd-navigation primary">
<ul>
<li class=" ">
<a href="modules.html">Modules</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/application.html">application</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/application_base.html">application/base</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/application_django.html">application/django</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/application_react.html">application/react</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/application_redis.html">application/redis</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/certificate.html">certificate</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/chart.html">chart</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/container.html">container</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/cronjob.html">cronjob</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/deployment.html">deployment</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/imports_acme_cert_manager_io.html">imports/acme.cert-<wbr>manager.io</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/imports_cert_manager_io.html">imports/cert-<wbr>manager.io</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/imports_k8s.html">imports/k8s</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/index.html">index</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/ingress.html">ingress</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/service.html">service</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/serviceaccount.html">serviceaccount</a>
</li>
<li class=" tsd-kind-module">
<a href="modules/utils.html">utils</a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
<li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
</ul>
</div>
</div>
</footer>
<div class="container tsd-generator">
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
</div>
<div class="overlay"></div>
<script src="assets/js/main.js"></script>
</body>
</html>