UNPKG

15 kBMarkdownView Raw
1# @idearium/cli
2
3The Idearium cli, which makes working with our projects, super easy :)
4
5## Documentation
6
7The cli is self documenting and you'll find limited information about the commands within the cli here.
8
9## Install
10
11Via NPM:
12
13```
14$ npm install -DE [-g] @idearium/cli
15```
16
17We actually recommend installing `@idearium/cli` locally in your project. This allows each project to use a different version of the cli. If you do however, we also recommend adding `./node_modules/.bin` to your path, so that you can run the cli via `c` without a global install.
18
19## Usage
20
21Once installed, simply run `c`, and you'll get the help output for all commands. Running a sub-command and then `--help` will give you the help output for that command (i.e. `c dc --help`).
22
23## Requirements
24
25The cli has been designed to work closely with [infrastructure-common](https://github.com/idearium/infrastructure-common). Infrastructure provides MongoDB, Redis, RabbitMQ and importantly for the cli, Kubernetes ingress.
26
27You can read more about how this all hangs together at https://github.com/idearium/developers/tree/master/stack
28
29## Commands
30
31The following is a summary of the top level commands.
32
33- `c d` is for everything Docker.
34- `c dc` is for everything Docker Compose.
35- `c hosts` helps with hosts management.
36- `c kc` is for everything kubectrl.
37- `c mk` is for everything Minikube.
38- `c mongo` is for MongoDB connections.
39- `c npm` is for everything NPM.
40- `c project` is for project management.
41- `c yarn` is for everything is for everything Yarn.
42
43Be aware that `kubectl` uses a global configuration, but the `c kc` command supercedes those where possible and ensures kubectl runs in the context of the project you're within.
44
45## Concepts
46
47The cli has two concepts to be aware of:
48
49- Configuration
50- State
51
52The cli can be highly configured within information about your project, and work with Docker, NPM and Kubernetes with the information provided. All configuration is stored within a `c.js` file that lives in the root of your project. This file should be stored in Git.
53
54The cli is designed to work with multiple environments. You put your project into a particular environment, and the commands run within the context of that environment. All state is stored in `devops/state.json` (this file should be added to `.gitignore`).
55
56## Configuration
57
58The Idearium cli can be customised through configurations. Configurations are provided through a `c.js` file located in projects root folder.
59
60The `c.js` should be a standard Node.js file. It will be loaded through `require`. The `c.js` should export an object, with the following keys representing configuration:
61
62```javascript
63module.exports = {
64 docker: {
65 // ...
66 },
67 environments: {
68 // ...
69 },
70 kubernetes: {
71 // ...
72 },
73 mongo: {
74 // ...
75 },
76 npm: {
77 // ...
78 },
79 project: {
80 // ...
81 },
82};
83```
84
85The command `c project init` can be used to initialise a project. It will generate a `c.js` file as a starting point, although, it will need to be completed.
86
87### Docker configuration
88
89The Idearium cli supports a Docker configuration. The Docker configuration can be used to define locations of multiple Dockerfiles within your project.
90
91An example Docker configuration:
92
93```JavaScript
94'use strict';
95
96const { exec } = require('shelljs');
97
98module.exports = {
99 docker: {
100 locations: {
101 'app': {
102 buildArgs: {
103 NPM_AUTH_TOKEN: () => exec('c npm auth -n', { silent: true }).stdout,
104 },
105 path: './app',
106 useTar: true,
107 },
108 'static': {
109 path: './static',
110 },
111 },
112 },
113};
114```
115
116The Docker configuration supports the following keys.
117
118#### locations
119
120The locations key should be an object, describing all Dockerfile locations in your project. Each key should be the name of a Dockerfile location. You can use the name to reference the location when using the cli. Each location supports the following structure.
121
122##### path
123
124A path to the Dockerfile location.
125
126##### buildArgs
127
128An object represent key=value `--build-arg` flags to pass to `docker build`. Each property should present a build argument name, and the value for the build argument. The value can be either a static value (i.e. string, number) or a function.
129
130##### useTar
131
132If `useTar` is set to true, `tar` will be used to prepare the Docker context and package and send files to the Docker daemon. This allows for some additional flexibility such as using symlinks which point outside the Dockerfile context.
133
134##### test
135
136You can supply a `test` object to enable the `c kc test <location>` command. `test` has the following properties:
137
138- `cmd` containing the command to run, inside the Docker container. It defaults to `npm test`.
139- `params` containing an object keyed by `docker run` parameter name. For example: `{ '-e': ['foo="bar"', 'bar="foo"'], '-w': '/app' }`. This allows you to customise the `docker run` command used when testing the image.
140
141### Environments configuration
142
143The Idearium cli supports multiple environments. The environments can be whatever you need them to be as long as you define them in `c.js`. Here is an example environments configuration:
144
145```JavaScript
146'use strict';
147
148module.exports = {
149 environments: {
150 local: { url: 'http://domain.name.local' },
151 production: { url: 'https://domain.name.com' },
152 },
153};
154```
155
156For each environment, you should provide a URL for the environment.
157
158### Kubernetes configuration
159
160You can supply a Kubernetes configuration. The configuration allows you to define contexts and namespaces for each environment your project supports, along with Kubernetes locations which describe the Kubernetes objects to deploy. Here is an example kubernetes configuration:
161
162```JavaScript
163'use strict';
164
165module.exports = {
166 kubernetes: {
167 environments: {
168 local: {
169 context: 'minikube',
170 locations: {
171 /* eslint-disable sort-keys */
172 'namespace': [
173 {
174 path: 'namespace',
175 templateLocals: ['environment', 'namespace'],
176 type: 'namespace',
177 },
178 ],
179 'app': [
180 {
181 path: 'app.deployment',
182 templateLocals: ['namespace', 'prefix', 'tag'],
183 type: 'deployment',
184 },
185 {
186 path: 'app.service',
187 templateLocals: ['namespace'],
188 type: 'service',
189 },
190 ],
191 'static': [
192 {
193 path: 'static.deployment',
194 templateLocals: ['namespace', 'prefix', 'tag'],
195 type: 'deployment',
196 },
197 {
198 path: 'static.service',
199 templateLocals: ['environment', 'namespace'],
200 type: 'service',
201 },
202 ],
203 /* eslint-enable sort-keys */
204 },
205 path: './manifests/local'
206 },
207 production: {
208 context: 'gke_focus-booster_us-east1-b_focus-booster',
209 namespace: 'override',
210 region: 'us-east1',
211 },
212 }
213 },
214};
215```
216
217The `kubernetes.environments` path holds a descrete environment. Each Kubernetes environment supports the following keys:
218
219- context, the kubectl context that should be used.
220- locations, the Kubernetes objects to work with.
221- namespace, if provied, will override the generated namespace.
222- path, the path to the folder containing Kuberentes manifest YAML files.
223- region, an optional region, mostly required for production.
224
225#### Kubernetes locations
226
227The Kuberentes locations object describes all Kubernetes objects for that Kuberentes environment. Each location should contain the following (`{}` used to represent meaning):
228
229```
230locations: {
231 {location-name}: [
232 {
233 dockerLocation: '',
234 path: '',
235 templateLocals: [],
236 type: '',
237 }
238 ]
239}
240```
241
242The `location-name` should be unique, and can be used within the cli commands to target a specific Kubernetes location.
243
244Each location should be an array of services. One Kubernetes location can contain multiple services.
245
246Each service object should provide:
247
248- `dockerLocation` (optional): The Docker location that a particular Kubernetes service object is associated with. This is usually provided with a `deployment` or `pod` object.
249- `path`: The filename within the Kubernetes environment path. The filename should not include the extension; but only `yaml` and `yaml.tmpl` are supported.
250- `templateLocals`: An array to provide a list of locals that should be passed to a `tmpl` file to create a `yaml` file.
251- `type`: The type of Kubernetes object this service describes (i.e. `pod`, `deployment`, `namespace`).
252
253##### YAML templates
254
255The `c kc apply` command supports templates, which will generate `yaml` files which will be used to deploy Kuberntes objects.
256
257It supports templates, because you'll often want to substitute specific information for Kubernetes during development. A good example is the `tag` that should be used with a particular image.
258
259If you'd like to use a template create Kubernetes manifest file ending in `.yaml.tmpl` rather than `tmpl`. The `path` in the Kubernetes location service object, should not contain the extension. In the template file use `{{tag}}` to substitute with an actual value before being applied to Kubernetes.
260
261You'll then need to supply all of the values that the template file requires. You provide this via the `templateLocals` array in the Kubernetes location service object. Here is an example:
262
263```
264{
265 path: 'app.deployment',
266 templateLocals: ['namespace', 'prefix', 'tag', () => { label: 'a', value: 'b' }],
267 type: 'deployment'
268}
269```
270
271The `c kc apply` will automatically provide the values for `namespace`, `prefix` and `tag`. If you'd like to provide something else, simply write a function that returns an object with `label` and `value`. Then use the value of `label` within a template placeholder (i.e. `{{a}}`) and it will be updated with the `value` (i.e. `{{b}}`).
272
273### MongoDB configuration
274
275The Idearium cli supports a MongoDB configuration. The MongoDB configuration can be used to access local and remote databases.
276
277An example MongoDB configuration:
278
279```JavaScript
280'use strict';
281
282module.exports = {
283 mongo: {
284 beta: {
285 host: 'dbhost.com',
286 name: 'db-beta',
287 password: 'password',
288 port: '12345',
289 ssl: true,
290 user: 'user',
291 },
292 local: {
293 host: 'db.common.idearium.local',
294 name: 'db',
295 port: '27017',
296 ssl: false,
297 },
298 beta: {
299 host: 'dbhost.com',
300 name: 'db',
301 password: 'password',
302 port: '12345',
303 ssl: true,
304 user: 'user',
305 },
306 },
307};
308```
309
310The MongoDB configuration supports the following keys.
311
312#### Environment
313
314Each top level key will be used as an `env` variable, setting the context for the commands. e.g. `c mongo connect local`.
315
316Each environment can contain the following keys `host`, `name`, `password`, `port`, `ssl`, and `user`.
317
318`password` and `user` are currently optional for local connections.
319
320### NPM configuration
321
322The Idearium cli supports an NPM configuration. The configuration can be used to provide the cli without information about where NPM commands can be run. To provide this information, add an `npm` property in `c.js` like so:
323
324```JavaScript
325'use strict';
326
327module.exports = {
328 npm: {
329 locations: {
330 name: './app/root/app/',
331 project: './',
332 },
333 },
334};
335```
336
337You should customise it, but you need to provide a `locations` key, containing an object with a name and folder for each NPM location in your project. You'll use the name to reference the location.
338
339For example, the `c npm proxy` command can be used to run a NPM command, at a specific location or all locations:
340
341- Execute `c npm proxy all install -SE logentries` to install the `logentries` module at all NPM locations in your project.
342- Execute `c npm proxy project install -DE jest` to install the `jest` module at the `project` location in your project.
343
344### Project configuration
345
346The Idearium cli supports a project configuration. This configuration is used to provide some general information about the project. This information is also used to automatically generate some strings such as the project prefix, and Kubernetes namespaces. Here is an example project configuration:
347
348```JavaScript
349'use strict';
350
351module.exports = {
352 project: {
353 name: 'www',
354 organisation: 'fb'
355 },
356};
357```
358
359## State
360
361The Idearium cli, understands the concept of state. The only state it manages at present is the environment of your project. The current environment of your project will be used in certain commands, but not all commands.
362
363State is stored in a JSON file at `./devops/state.json`, and is created and written to by the `c project env set` and `c project setup` commands.
364
365## Ngrok
366
367The Idearium cli can be used to easily expose a Kubernetes service to the world via Ngrok, and the `c kc ngrok` command.
368
369To use this command, however, you need to provide a configuration file for Ngrok. Follow these steps.
370
3711. Create a file at `./manifests/local/ngrok.configmap.yaml.tmpl`.
3722. Add the code from the _Manifest template_ (below) to the file and update `<authtoken>` with your Ngrok authtoken (or remove that line) and update `<hostname>` with the hostname you'd like the tunnel to be exposed at.
3733. Added the code from the _Kubernetes location_ (below) to `c.js` in the `kubernetes.environments.local.locations` array.
3744. Then run `c kc ngrok start` in a new terminal (after running `c mk docker-env`).
3755. To stop, issue `CTRL + C`, then run `c kc ngrok stop` to stop ngrok.
376
377**Manifest template**:
378```
379apiVersion: v1
380kind: ConfigMap
381metadata:
382 name: ngrok
383 namespace: {{namespace}}
384data:
385 ngrok.yaml: |
386 authtoken: <authtoken>
387 console_ui: false
388 log: stdout
389 region: au
390 tunnels:
391 http:
392 proto: http
393 bind_tls: false
394 addr: static:80
395 hostname: <hostname>
396 update: false
397```
398
399**Kubernetes location**:
400```
401'ngrok': [
402 {
403 path: 'ngrok.configmap',
404 templateLocals: ['namespace'],
405 type: 'configmap',
406 },
407],
408```