├── .gitignore ├── README.md ├── _config.yml ├── module-02 - docker ├── example1-docker │ ├── README.md │ └── nodejs-with-mongodb-api-example │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── index.ts │ │ ├── package.json │ │ └── tsconfig.json ├── example2-docker-compose │ ├── README.md │ └── nodejs-with-mongodb-api-example │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── docker-compose.yml │ │ ├── index.ts │ │ ├── package.json │ │ └── tsconfig.json └── example3-dockerhub │ ├── README.md │ └── nodejs-with-mongodb-api-example │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yml │ ├── index.ts │ ├── package.json │ └── tsconfig.json ├── module-04 - k8s-on-azure ├── 1. container-registry.sh ├── 2. container-services.sh ├── 3. aks-kubernetes-az.sh └── README.md ├── module-05 - pods ├── 1. aks - working with pods.sh └── heroes-pod.json ├── module-06 - secrets ├── 1. aks - working with secrets.sh ├── docker-registry-secret.json ├── heroes-pod.json └── secret.yaml ├── module-07 - replicaSets ├── heroes-rs.json └── working with replicaSets.sh ├── module-08 - services ├── heroes-pod.json ├── heroes-svc.json ├── mongodb-pod.json ├── mongodb-svc.json └── scripts.sh ├── module-09 - deployments ├── README.md ├── heroes-deploy.json ├── heroes-svc.json ├── mongodb-deploy.json ├── mongodb-svc.json └── scripts.sh ├── module-10 - rolling updates ├── heroes-deploy.json ├── nodejs-with-mongodb-api-example │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yml │ ├── index.ts │ ├── package.json │ └── tsconfig.json └── scripts.sh ├── module-11 - ingress controllers ├── 1. nginx-default-backend.yaml ├── 2. ingress-controller-nginx.yaml ├── 3. nginx.yaml ├── 4. demo.yaml └── script.sh ├── module-12 - statefulSet └── mongodb.stateful.json ├── module-13 - volumes ├── 1. persistent-volume.json ├── 2. persistent-volume-claim.json ├── 3. upload-app.json └── scripts.sh ├── module-14 - jobs and cronjobs ├── 1. job │ ├── job-example │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Index.ts │ │ ├── docker-compose.yml │ │ ├── package-lock.json │ │ ├── package.json │ │ └── tsconfig.json │ └── job.json └── 2. cron-job │ └── cron-job.json ├── module-15 - namespaces ├── docker-registry-secret.json ├── heroes-deploy.json ├── heroes-svc.json ├── namespace.dev.json ├── namespace.prod.json └── scripts.sh └── module-16 - resource monitoring and auto-scale ├── 1. working with OMS └── oms-agent.yaml ├── 2. kubedash └── kubedash.yaml ├── 3. horizontal pod auto scalling ├── api-heroes-autoscaling.json └── script.sh └── 4. slack notification ├── 1. watcher-error.yaml └── 2. test-error.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bem vindo à Maratona Kubernetes 2 | 3 | capa maratona kubernetes 4 | 5 | Inscrições: [http://aka.ms/maratonakubernetes](http://aka.ms/maratonakubernetes) 6 | 7 | ## SOBRE O TREINAMENTO 8 | 9 | Ganhar eficiência e velocidade é uma busca constante em times de desenvolvimento em startups e grandes corporações, com o objetivo de aprimorar a qualidade de entrega do software e facilitar sua gestão e distribuição. Ferramentas e práticas, facilitam este processo de transição e potencialização de arquitetura. Entre as ferramentas, destaca-se o Kubernetes, um orquestrador de containers Open Source. 10 | 11 | O Kubernetes é mais que um orquestrador de containers. Com ele, é possível gerenciar aplicativos em containers e escalá-los de forma ágil, além de ter a possibilidade de automatizar processos de implantação e atualização, seja em uma única máquina ou em milhares de máquinas em múltiplos hosts. 12 | 13 | Durante o treinamento, será possível aprender os conceitos de Kubernetes, e através de atividades práticas, a analisar e desenhar a implantação de orquestração de containers. Todas as atividades são orientadas a situações do cotidiano de empresas, passando por desafios como monitoramento de recursos, escala automática e segurança, utilizando o AKS e outras ferramentas do Azure. 14 | 15 | ## PRÉ-REQUISITOS 16 | 17 | Conhecimentos básicos em Git, Linux, DevOps e Cloud irão contribuir para você obter o melhor aproveitamento do treinamento. Saiba mais sobre containers e AKS. 18 | Conta gratuita para desenvolvedores no Azure Free Trial. Você receberá gratuitamente U$ 200,00 em créditos para usar em qualquer produto Azure por 30 dias + 12 meses de acesso à mais de 25 produtos. 19 | 20 | ## INSTRUTOR 21 | 22 | ### [Erick Wendel](https://github.com/erickwendel) 23 | 24 | Pós-graduando em Business Intelligence with Big Data. Microsoft Most Valuable Professional (MVP). Fundador da EW.IT, Microsoft Certified Professional, Microsoft Specialist. Possui amplo conhecimento em desenvolvimento de software, experiência em arquitetura, desenvolvimento e segurança de aplicações. Palestrante nas maiores conferências de JavaScript, Node.js e segurança da América latina. 25 | 26 | ## CONTEÚDO 27 | 28 | ### MÓDULO 1: INTRODUÇÃO 29 | 30 | * Lição 1: Apresentação do curso e do autor 31 | * Lição 2: Objetivos do curso 32 | * Lição 3: Introdução ao curso 33 | * Lição 4: Data center orientado a código e Desired State versus Current State 34 | 35 | ### MÓDULO 2: DOCKER & CONTAINERS 36 | 37 | * Lição 1: O que são containers 38 | * Lição 2: Introdução ao Docker 39 | * Lição 3: [Hands-on - Docker](module-02%20-%20docker/example1-docker) 40 | * Lição 4: [Hands-on - Docker compose](module-02%20-%20docker/example2-docker-compose) 41 | * Lição 5: [Hands-on - Docker hub](module-02%20-%20docker/example3-dockerhub) 42 | 43 | ### MÓDULO 3: PRINCÍPIOS DE KUBERNETES 44 | 45 | * Lição 1: Apresentação do capitulo 46 | * Lição 2: Kubernetes? 47 | * Lição 3: Arquitetura K8s: Clusters, Masters 48 | * Lição 4: Nodes 49 | * Lição 5: Declarative Model versus Desired State 50 | * Lição 6: Pods e Containers 51 | * Lição 7: Services 52 | * Lição 8: Deployments 53 | 54 | ### MÓDULO 4: K8S EM AÇÃO - TRABALHANDO COM KUBERNETES NO AZURE 55 | 56 | * Lição 1: [Hands-on - ACR - Azure Container Registry](module-04%20-%20k8s-on-azure/1.%20container-registry.sh) 57 | * Lição 2: [Hands-on - ACI - Azure Container Instances](module-04%20-%20k8s-on-azure/2.%20container-services.sh) 58 | * Lição 3: [Hands-on - AKS - Azure Kubernetes Service](module-04%20-%20k8s-on-azure/3.%20aks-kubernetes-az.sh) 59 | 60 | ### MÓDULO 5: PODS 61 | 62 | * Lição 1: Apresentação do capítulo 63 | * Lição 2: [Hands-on - Iterative Model](module-05%20-%20pods/1.%20aks%20-%20working%20with%20pods.sh) 64 | * Lição 3: [Hands-on - Declarative Model](module-05%20-%20pods) 65 | * Lição 4: [Hands-on - Gerenciamento de pods](module-05%20-%20pods/1.%20aks%20-%20working%20with%20pods.sh) 66 | 67 | ### MÓDULO 6: SECRETS 68 | 69 | * Lição 1: Apresentação do capítulo 70 | * Lição 2: [Hands-on - Trabalhando com Imagens Privadas](module-06%20-%20secrets) 71 | 72 | ### MÓDULO 7: REPLICASETS 73 | 74 | * Lição 1: Introdução 75 | * Lição 2: [Hands-on - ReplicaSets](module-07%20-%20replicaSets) 76 | 77 | ### MÓDULO 8: SERVICES 78 | 79 | * Lição 1: Apresentação do capítulo 80 | * Lição 2: [Hands-on - Iterative Model](module-08%20-%20services/scripts.sh) 81 | * Lição 3: [Hands-on - Declarative Model](module-08%20-%20services) 82 | 83 | ### MÓDULO 9: DEPLOYMENTS 84 | 85 | * Lição 1: Apresentação do capítulo 86 | * Lição 2: [Hands-on - Declarative Model](module-09%20-%20deployments) 87 | 88 | ### MÓDULO 10: ROLLING UPDATES 89 | 90 | * Lição 1: Apresentação do capítulo 91 | * Lição 2: [Hands-on - Gerenciando versões e historico de atualizações](module-10%20-%20rolling%20updates) 92 | 93 | ### MÓDULO 11: INGRESS CONTROLLERS 94 | 95 | * Lição 1: Apresentação do capítulo 96 | * Lição 2: [Hands-on - Ingress Controllers](module-11%20-%20ingress%20controllers) 97 | 98 | ### MÓDULO 12: STATEFULSET 99 | 100 | * Lição 1: Apresentação do capítulo 101 | * Lição 2: [Hands-on - StatefulSet](module-12%20-%20statefulSet) 102 | 103 | ### MÓDULO 13: PERSISTENT VOLUMES 104 | 105 | * Lição 1: Apresentação do capítulo 106 | * Lição 2: Contaner Stateless? 107 | * Lição 3: [Hands-on - Persistent volumes com Azure Disks](module-13%20-%20volumes) 108 | 109 | ### MÓDULO 14: JOBS AND CRON JOBS 110 | 111 | * Lição 1: Apresentação do capítulo 112 | * Lição 2: [Hands-on - Jobs](module-14%20-%20jobs%20and%20cronjobs/1.%20job) 113 | * Lição 3: [Hands-on - Cron Jobs](module-14%20-%20jobs%20and%20cronjobs/2.%20cron-job) 114 | 115 | ### MÓDULO 15: NAMESPACES 116 | 117 | * Lição 1: Apresentação do capítulo 118 | * Lição 2: [Hands-on - Namespaces](module-15%20-%20namespaces) 119 | 120 | ### MÓDULO 16: MONITORAMENTO DE RECURSOS E AUTO-SCALING 121 | 122 | * Lição 1: Apresentação do capítulo 123 | * Lição 2: [Hands-on - Monitoramento e alertas com Slack Webhooks](module-16%20-%20resource%20monitoring%20and%20auto-scale/4.%20slack%20notification) 124 | * Lição 3: [Hands-on - Conhecendo o OMS](module-16%20-%20resource%20monitoring%20and%20auto-scale/1.%20working%20with%20OMS) 125 | * Lição 4: [Hands-on - Monitoramento e Análise de clusters e containers Com KubeDash](module-16%20-%20resource%20monitoring%20and%20auto-scale/2.%20kubedash) 126 | * Lição 5: [Hands-on - Gerenciando recursos e auto scalling](module-16%20-%20resource%20monitoring%20and%20auto-scale/3.%20horizontal%20pod%20auto%20scalling) 127 | 128 | ### MÓDULO 17: PRÓXIMOS PASSOS 129 | 130 | * Lição 1: Próximos Passos 131 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/README.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | ## Docker 4 | 5 | `docker run hello-world` 6 | 7 | `docker run -it node:8-alpine bash` 8 | 9 | `docker ps` 10 | 11 | ### Testing node on container 12 | 13 | `node -e '1+1' -p` 14 | 15 | ### Dockerizing our apps 16 | 17 | `git clone https://github.com/ErickWendel/nodejs-with-mongodb-api-example.git` 18 | 19 | `cd nodejs-with-mongodb-api-example` 20 | 21 | `npm i` 22 | 23 | `npm run build` 24 | 25 | `npm start #causes exception because mongoDB is not installed` 26 | 27 | `touch Dockerfile .dockerignore` 28 | 29 | `docker run -d --name mongodb mongo:3.5` 30 | 31 | `docker build -t api-example .` 32 | 33 | `docker run -p 3000:3000 --link mongodb:mongo -e MONGO_URL=mongodb api-example` 34 | 35 | #### Linux Systems 36 | 37 | Obs: if you are on linux sytem, npm install script, fails because you need `sudo` permissions. Try to run `sudo npm i -g typescript` and remove `"preinstall": "npm i -g typescript"` line from [package.json](nodejs-with-mongodb-api-example/package.json#L7), after that, try `npm i` again. 38 | -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | ADD . /src 4 | 5 | WORKDIR /src 6 | 7 | RUN npm i -g typescript 8 | 9 | RUN npm i 10 | 11 | RUN npm run build 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/README.md: -------------------------------------------------------------------------------- 1 | ## Node.js with MongoDB Example 2 | 3 | Swagger Page of that application 4 | 5 | ### Requirements 6 | 7 | * Node.js v7+ 8 | * MongoDB running on local instance 9 | 10 | ### Running 11 | 12 | * Install dependencies - `npm i` 13 | * Build typescript - `npm run build` 14 | * Run project - `npm start` 15 | * Go to swagger page - `localhost:3000/documentation` 16 | -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/index.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from "hapi"; 2 | import * as Joi from "joi"; 3 | import { MongoClient } from "mongodb"; 4 | 5 | const Inert = require("inert"); 6 | const Vision = require("vision"); 7 | const HapiSwagger = require("hapi-swagger"); 8 | const server = new Hapi.Server(); 9 | const port = process.env.PORT || 3000; 10 | server.connection({ port }); 11 | 12 | (async () => { 13 | const connectionString = `mongodb://${process.env.MONGO_URL || 14 | "localhost"}/heroes`; 15 | const connection = await MongoClient.connect(connectionString); 16 | console.log("mongo db is running"); 17 | const db = connection.db("heroes").collection("hero"); 18 | await server.register([ 19 | Inert, 20 | Vision, 21 | { 22 | register: HapiSwagger, 23 | options: { 24 | info: { 25 | title: "Node.js with MongoDB Example - Erick Wendel", 26 | version: "1.0" 27 | } 28 | } 29 | } 30 | ]); 31 | 32 | server.route([ 33 | { 34 | method: "GET", 35 | path: "/heroes", 36 | config: { 37 | handler: (req: any, reply: any) => { 38 | return reply(db.find().toArray()); 39 | }, 40 | description: "List All heroes", 41 | notes: "heroes from database", 42 | tags: ["api"] 43 | } 44 | }, 45 | { 46 | method: "POST", 47 | path: "/heroes", 48 | config: { 49 | handler: (req, reply) => { 50 | const { payload } = req; 51 | return reply(db.insert(payload)); 52 | }, 53 | description: "Create a hero", 54 | notes: "create a hero", 55 | tags: ["api"], 56 | validate: { 57 | payload: { 58 | name: Joi.string().required(), 59 | power: Joi.string().required() 60 | } 61 | } 62 | } 63 | }, 64 | 65 | { 66 | method: "DELETE", 67 | path: "/heroes/{id}", 68 | config: { 69 | handler: (req, reply) => { 70 | return reply(db.remove({ _id: req.params.id })); 71 | }, 72 | description: "Delete a hero", 73 | notes: "Delete a hero", 74 | tags: ["api"], 75 | validate: { 76 | params: { 77 | id: Joi.string().required() 78 | } 79 | } 80 | } 81 | } 82 | ]); 83 | 84 | await server.start(); 85 | console.log("server running at", port); 86 | })(); 87 | -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "preinstall": "npm i -g typescript", 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "start": "node lib/index.js", 10 | "build": "tsc" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@types/hapi": "^15.0.2", 17 | "@types/joi": "^13.0.5", 18 | "@types/mongodb": "^3.0.5", 19 | "hapi": "^15.2.0", 20 | "hapi-swagger": "^7.10.0", 21 | "inert": "^4.2.1", 22 | "joi": "^13.1.2", 23 | "mongodb": "^3.0.3", 24 | "vision": "^4.1.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /module-02 - docker/example1-docker/nodejs-with-mongodb-api-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": 5 | "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */, 6 | "module": 7 | "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 8 | "lib": [ 9 | "es2015" 10 | ] /* Specify library files to be included in the compilation: */, 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "lib" /* Redirect output structure to the directory. */, 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": false /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 31 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 32 | 33 | /* Additional Checks */ 34 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 35 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 36 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 37 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 38 | 39 | /* Module Resolution Options */ 40 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 41 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 42 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 43 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 44 | // "typeRoots": [], /* List of folders to include type definitions from. */ 45 | // "types": [], /* Type declaration files to be included in compilation. */ 46 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 47 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 48 | 49 | /* Source Map Options */ 50 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 51 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 52 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 53 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 54 | 55 | /* Experimental Options */ 56 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 57 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/README.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | ## Docker 4 | 5 | ```sh 6 | docker-compose up 7 | docker-compose down 8 | ``` 9 | 10 | ```sh 11 | # if changes on application code docker-compose up -- build 12 | ``` 13 | -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | ADD . /src 4 | 5 | WORKDIR /src 6 | 7 | RUN npm i -g typescript 8 | 9 | RUN npm i 10 | 11 | RUN npm run build 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/README.md: -------------------------------------------------------------------------------- 1 | ## Node.js with MongoDB Example 2 | 3 | Swagger Page of that application 4 | 5 | ### Requirements 6 | 7 | * Node.js v7+ 8 | * MongoDB running on local instance 9 | 10 | ### Running 11 | 12 | * Install dependencies - `sudo npm i` 13 | * Build typescript - `npm run build` 14 | * Run project - `npm start` 15 | * Go to swagger page - `localhost:3000/documentation` 16 | -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | api-heroes: 4 | build: . 5 | ports: 6 | - 3000:3000 7 | environment: 8 | MONGO_URL: mongodb 9 | links: 10 | - mongodb 11 | 12 | mongodb: 13 | image: mongo:3.5 14 | ports: 15 | - 27017:2017 -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/index.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from "hapi"; 2 | import * as Joi from "joi"; 3 | import { MongoClient } from "mongodb"; 4 | 5 | const Inert = require("inert"); 6 | const Vision = require("vision"); 7 | const HapiSwagger = require("hapi-swagger"); 8 | const server = new Hapi.Server(); 9 | const port = process.env.PORT || 3000; 10 | server.connection({ port }); 11 | 12 | (async () => { 13 | const connectionString = `mongodb://${process.env.MONGO_URL || 14 | "localhost"}/heroes`; 15 | const connection = await MongoClient.connect(connectionString); 16 | console.log("mongo db is running"); 17 | const db = connection.db("heroes").collection("hero"); 18 | await server.register([ 19 | Inert, 20 | Vision, 21 | { 22 | register: HapiSwagger, 23 | options: { 24 | info: { 25 | title: "Node.js with MongoDB Example - Erick Wendel - Updated", 26 | version: "2.0" 27 | } 28 | } 29 | } 30 | ]); 31 | 32 | server.route([ 33 | { 34 | method: "GET", 35 | path: "/heroes", 36 | config: { 37 | handler: (req: any, reply: any) => { 38 | return reply(db.find().toArray()); 39 | }, 40 | description: "List All heroes", 41 | notes: "heroes from database", 42 | tags: ["api"] 43 | } 44 | }, 45 | { 46 | method: "POST", 47 | path: "/heroes", 48 | config: { 49 | handler: (req, reply) => { 50 | const { payload } = req; 51 | return reply(db.insert(payload)); 52 | }, 53 | description: "Create a hero", 54 | notes: "create a hero", 55 | tags: ["api"], 56 | validate: { 57 | payload: { 58 | name: Joi.string().required(), 59 | power: Joi.string().required() 60 | } 61 | } 62 | } 63 | }, 64 | 65 | { 66 | method: "DELETE", 67 | path: "/heroes/{id}", 68 | config: { 69 | handler: (req, reply) => { 70 | return reply(db.remove({ _id: req.params.id })); 71 | }, 72 | description: "Delete a hero", 73 | notes: "Delete a hero", 74 | tags: ["api"], 75 | validate: { 76 | params: { 77 | id: Joi.string().required() 78 | } 79 | } 80 | } 81 | } 82 | ]); 83 | 84 | await server.start(); 85 | console.log("server running at", port); 86 | })(); 87 | -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "preinstall": "npm i -g typescript", 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "start": "node lib/index.js", 10 | "build": "tsc" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@types/hapi": "^15.0.2", 17 | "@types/joi": "^13.0.5", 18 | "@types/mongodb": "^3.0.5", 19 | "hapi": "^15.2.0", 20 | "hapi-swagger": "^7.10.0", 21 | "inert": "^4.2.1", 22 | "joi": "^13.1.2", 23 | "mongodb": "^3.0.3", 24 | "vision": "^4.1.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /module-02 - docker/example2-docker-compose/nodejs-with-mongodb-api-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": 5 | "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */, 6 | "module": 7 | "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 8 | "lib": [ 9 | "es2015" 10 | ] /* Specify library files to be included in the compilation: */, 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "lib" /* Redirect output structure to the directory. */, 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": false /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 31 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 32 | 33 | /* Additional Checks */ 34 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 35 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 36 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 37 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 38 | 39 | /* Module Resolution Options */ 40 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 41 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 42 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 43 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 44 | // "typeRoots": [], /* List of folders to include type definitions from. */ 45 | // "types": [], /* Type declaration files to be included in compilation. */ 46 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 47 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 48 | 49 | /* Source Map Options */ 50 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 51 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 52 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 53 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 54 | 55 | /* Experimental Options */ 56 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 57 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/README.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | ## Docker 4 | 5 | `docker login` 6 | 7 | `docker images` 8 | 9 | `REGISTRY=erickwendel #your username` 10 | 11 | `docker tag nodejswithmongodbapiexample_api-heroes $REGISTRY/api-heroes` 12 | 13 | `docker images` 14 | 15 | `docker push erickwendel/api-heroes` 16 | 17 | `docker rmi erickwendel/api-heroes` 18 | 19 | `#update your docker-compose with erickwende/api-heroes image name` 20 | 21 | `cd nodejs-with-mongodb-api-example` 22 | 23 | `docker-compose up` 24 | 25 | `# alter some text in your application` 26 | 27 | `docker build -t erickwendel/api-heroes .` 28 | 29 | `docker push erickwendel/api-heroes` 30 | 31 | `docker-compose down` 32 | 33 | `docker rmi $(docker images | grep api-) | awk '{print $3}')` 34 | 35 | `docker pull erickwendel/api-heroes` 36 | 37 | `docker-compose up` -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | ADD . /src 4 | 5 | WORKDIR /src 6 | 7 | RUN npm i -g typescript 8 | 9 | RUN npm i 10 | 11 | RUN npm run build 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/README.md: -------------------------------------------------------------------------------- 1 | ## Node.js with MongoDB Example 2 | 3 | Swagger Page of that application 4 | 5 | ### Requirements 6 | 7 | * Node.js v7+ 8 | * MongoDB running on local instance 9 | 10 | ### Running 11 | 12 | * Install dependencies - `npm i` 13 | * Build typescript - `npm run build` 14 | * Run project - `npm start` 15 | * Go to swagger page - `localhost:3000/documentation` 16 | -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | api-heroes: 4 | # build: . 5 | image: erickwendel/api-heroes 6 | ports: 7 | - 3000:3000 8 | environment: 9 | MONGO_URL: mongodb 10 | links: 11 | - mongodb 12 | 13 | mongodb: 14 | image: mongo:3.5 15 | ports: 16 | - 27017:2017 -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/index.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from "hapi"; 2 | import * as Joi from "joi"; 3 | import { MongoClient } from "mongodb"; 4 | 5 | const Inert = require("inert"); 6 | const Vision = require("vision"); 7 | const HapiSwagger = require("hapi-swagger"); 8 | const server = new Hapi.Server(); 9 | const port = process.env.PORT || 3000; 10 | server.connection({ port }); 11 | 12 | (async () => { 13 | const connectionString = `mongodb://${process.env.MONGO_URL || 14 | "localhost"}/heroes`; 15 | const connection = await MongoClient.connect(connectionString); 16 | console.log("mongo db is running"); 17 | const db = connection.db("heroes").collection("hero"); 18 | await server.register([ 19 | Inert, 20 | Vision, 21 | { 22 | register: HapiSwagger, 23 | options: { 24 | info: { 25 | title: "Node.js with MongoDB Example - Erick Wendel - Updated", 26 | version: "2.0" 27 | } 28 | } 29 | } 30 | ]); 31 | 32 | server.route([ 33 | { 34 | method: "GET", 35 | path: "/heroes", 36 | config: { 37 | handler: (req: any, reply: any) => { 38 | return reply(db.find().toArray()); 39 | }, 40 | description: "List All heroes", 41 | notes: "heroes from database", 42 | tags: ["api"] 43 | } 44 | }, 45 | { 46 | method: "POST", 47 | path: "/heroes", 48 | config: { 49 | handler: (req, reply) => { 50 | const { payload } = req; 51 | return reply(db.insert(payload)); 52 | }, 53 | description: "Create a hero", 54 | notes: "create a hero", 55 | tags: ["api"], 56 | validate: { 57 | payload: { 58 | name: Joi.string().required(), 59 | power: Joi.string().required() 60 | } 61 | } 62 | } 63 | }, 64 | 65 | { 66 | method: "DELETE", 67 | path: "/heroes/{id}", 68 | config: { 69 | handler: (req, reply) => { 70 | return reply(db.remove({ _id: req.params.id })); 71 | }, 72 | description: "Delete a hero", 73 | notes: "Delete a hero", 74 | tags: ["api"], 75 | validate: { 76 | params: { 77 | id: Joi.string().required() 78 | } 79 | } 80 | } 81 | } 82 | ]); 83 | 84 | await server.start(); 85 | console.log("server running at", port); 86 | })(); 87 | -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "preinstall": "npm i -g typescript", 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "start": "node lib/index.js", 10 | "build": "tsc" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@types/hapi": "^15.0.2", 17 | "@types/joi": "^13.0.5", 18 | "@types/mongodb": "^3.0.5", 19 | "hapi": "^15.2.0", 20 | "hapi-swagger": "^7.10.0", 21 | "inert": "^4.2.1", 22 | "joi": "^13.1.2", 23 | "mongodb": "^3.0.3", 24 | "vision": "^4.1.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /module-02 - docker/example3-dockerhub/nodejs-with-mongodb-api-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": 5 | "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */, 6 | "module": 7 | "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 8 | "lib": [ 9 | "es2015" 10 | ] /* Specify library files to be included in the compilation: */, 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "lib" /* Redirect output structure to the directory. */, 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": false /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 31 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 32 | 33 | /* Additional Checks */ 34 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 35 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 36 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 37 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 38 | 39 | /* Module Resolution Options */ 40 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 41 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 42 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 43 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 44 | // "typeRoots": [], /* List of folders to include type definitions from. */ 45 | // "types": [], /* Type declaration files to be included in compilation. */ 46 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 47 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 48 | 49 | /* Source Map Options */ 50 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 51 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 52 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 53 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 54 | 55 | /* Experimental Options */ 56 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 57 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /module-04 - k8s-on-azure/1. container-registry.sh: -------------------------------------------------------------------------------- 1 | RESOURCE=k8s-course 2 | LOCATION=eastus 3 | REGISTRY_NAME=k8scourse 4 | REGISTRY_URL=$REGISTRY_NAME.azurecr.io 5 | PRIVATE_APP_NAME=$REGISTRY_URL/api-heroes 6 | 7 | # az group create --name $RESOURCE --location $LOCATION 8 | 9 | az account set --subscription "$SUBSCRIPTION" 10 | 11 | 12 | az acr create --resource-group $RESOURCE --name $REGISTRY_NAME --sku Basic 13 | 14 | az acr login --name $REGISTRY_NAME 15 | 16 | docker images 17 | 18 | az acr list --resource-group $RESOURCE \ 19 | --query "[].{acrLoginServer:loginServer}" \ 20 | --output table 21 | 22 | 23 | docker tag erickwendel/api-heroes $PRIVATE_APP_NAME 24 | 25 | docker images 26 | 27 | az acr login --resource-group $RESOURCE --name $REGISTRY_NAME 28 | 29 | docker push $PRIVATE_APP_NAME 30 | -------------------------------------------------------------------------------- /module-04 - k8s-on-azure/2. container-services.sh: -------------------------------------------------------------------------------- 1 | RESOURCE=k8s-course-1 2 | ACR=k8scourse 3 | REGISTRY=${ACR}.azurecr.io 4 | MONGO_DNS=mongodb 5 | APP_NAME=api-heroes 6 | IMAGE_NAME=$REGISTRY/$APP_NAME 7 | LOCATION=eastus 8 | 9 | sudo az group create --name $RESOURCE --location $LOCATION 10 | 11 | echo '--------------------CONTAINER REGISTRY------------------------------' 12 | 13 | az acr create --resource-group $RESOURCE --name $ACR --sku Basic --admin-enabled true 14 | az acr login --name $ACR 15 | 16 | #sudo docker tag api $IMAGE_NAME 17 | sudo docker push $IMAGE_NAME 18 | 19 | echo '--------------------CONTAINER SERVICES------------------------------' 20 | 21 | 22 | echo 'creating mongodb' 23 | 24 | az container create --resource-group $RESOURCE\ 25 | --name $MONGO_DNS --image mongo:3.5 \ 26 | --cpu 1 --memory 1 \ 27 | --port 27017 \ 28 | --ip-address public 29 | 30 | az acr update -n $ACR --admin-enabled true 31 | 32 | echo 'getting acr pass' 33 | 34 | ACR_PASS=$(az acr credential show -n $ACR --query passwords[0].value) 35 | ACR_PASS="${ACR_PASS//\"}" 36 | 37 | echo 'getting mongoDb IP' 38 | 39 | MONGO_IP=$(az container show --resource-group $RESOURCE --name $MONGO_DNS --query ipAddress.ip) 40 | MONGO_IP="${MONGO_IP//\"}" 41 | 42 | echo 'creating application' 43 | 44 | az container create --resource-group $RESOURCE\ 45 | --name $APP_NAME --image $IMAGE_NAME\ 46 | --cpu 1 --memory 1 \ 47 | --registry-username $ACR\ 48 | --registry-password $ACR_PASS \ 49 | --port 3000 \ 50 | --environment-variables MONGO_URL=$MONGO_IP\ 51 | --ip-address public 52 | 53 | az container logs --resource-group $RESOURCE --name $APP_NAME 54 | az container show --resource-group $RESOURCE --name $APP_NAME 55 | 56 | az container delete --name $APP_NAME --resource-group $RESOURCE --yes 57 | az container delete --name $MONGO_DNS --resource-group $RESOURCE --yes 58 | 59 | az group delete -n $RESOURCE --yes -------------------------------------------------------------------------------- /module-04 - k8s-on-azure/3. aks-kubernetes-az.sh: -------------------------------------------------------------------------------- 1 | RESOURCE=k8s-course-aks 2 | CLUSTER_NAME=k8s-cluster 3 | ADMIN_USER_NAME=azureuser 4 | ADMIN_USER_PWD=Erick@123345 5 | VM_SIZE=Standard_B1s 6 | LOCATION=eastus 7 | # eastus, westeurope, centralus, canadacentral, canadaeast 8 | az group create --name $RESOURCE --location $LOCATION 9 | 10 | az provider register -n Microsoft.ContainerService 11 | az provider register -n Microsoft.Storage 12 | az provider register -n Microsoft.Network 13 | az provider register -n Microsoft.Compute 14 | 15 | # az aks install-cli 16 | 17 | # az aks create –n $CLUSTER_NAME –g $RESOURCE 18 | # sudo chown -R $(whoami) / usr/local/bin 19 | 20 | # sudo chmod 755 /usr/local/lib 21 | 22 | az aks create -g k8s-course-aks-1\ 23 | --name k8s-cluster\ 24 | --dns-name-prefix k8s-cluster\ 25 | --node-vm-size Standard_B1s 26 | --node-count 2 27 | 28 | time; 29 | az aks create --resource-group $RESOURCE\ 30 | --name $CLUSTER_NAME \ 31 | --dns-name-prefix $CLUSTER_NAME \ 32 | --generate-ssh-keys \ 33 | --node-count 1 \ 34 | --node-vm-size $VM_SIZE 35 | time; 36 | 37 | az aks get-credentials --resource-group $RESOURCE --name $CLUSTER_NAME 38 | 39 | az aks browse --resource-group $RESOURCE --name $CLUSTER_NAME 40 | 41 | az aks delete --name $CLUSTER_NAME --resource-group $RESOURCE --yes 42 | 43 | az group delete --name $RESOURCE --yes 44 | 45 | az aks scale --resource-group=myResourceGroup --name=myAKSCluster --node-count 3 46 | 47 | kubectl scale --replicas=5 deployment/azure-vote-front 48 | 49 | -------------------------------------------------------------------------------- /module-04 - k8s-on-azure/README.md: -------------------------------------------------------------------------------- 1 | #Commands 2 | 3 | `kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml` 4 | 5 | `kubectl proxy` 6 | 7 | `http://localhost:8001/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/#!/overview?namespace=default` -------------------------------------------------------------------------------- /module-05 - pods/1. aks - working with pods.sh: -------------------------------------------------------------------------------- 1 | ¡ 2 | az acr list 3 | ACR_NAME=k8scourse 4 | 5 | kubectl describe deployment api-heroes 6 | 7 | kubectl run mongodb --image=mongo:3.5 --port=27017 8 | 9 | kubectl run api-heroes \ 10 | --replicas=2 \ 11 | --image=erickwendel/nodejs-with-mongodb-example \ 12 | --env="MONGO_URL=10.244.0.109" \ 13 | --port=4000 14 | 15 | # kubectl expose deployment api-heroes --port=4000 --type=LoadBalancer 16 | kubectl expose -f heroes-pod.json --port 4000 --type=LoadBalancer 17 | kubectl get services -w 18 | 19 | #kubectl delete pod api-heroes-66964b8f9b-h6w8m --recria 20 | 21 | kubectl delete deployment api-heroes 22 | 23 | kubectl explain pods,svc 24 | 25 | kubectl get pods -o wide 26 | 27 | kubectl describe pods my-pod 28 | 29 | kubectl get pods --selector=app=cassandra rc -o \ 30 | jsonpath='{.items[*].metadata.labels.version}' 31 | 32 | kubectl top pod 33 | 34 | kubectl logs my-pod 35 | 36 | 37 | kubectl exec -it envar-demo -- /bin/bash 38 | kubectl get pod mongodb-77fc45979b-wphhm -o yaml | grep podIP -------------------------------------------------------------------------------- /module-05 - pods/heroes-pod.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Pod", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "zone": "prod", 8 | "version": "v1" 9 | } 10 | }, 11 | "spec": { 12 | "containers": [{ 13 | "name": "api-heroes", 14 | "image": "erickwendel/nodejs-with-mongodb-example", 15 | "ports": [{ 16 | "containerPort": 4000 17 | }], 18 | "env": [{ 19 | "name": "MONGO_URL", 20 | "value": "10.244.0.109" 21 | }, 22 | { 23 | "name": "PORT", 24 | "value": "4000" 25 | } 26 | ] 27 | }] 28 | } 29 | } -------------------------------------------------------------------------------- /module-06 - secrets/1. aks - working with secrets.sh: -------------------------------------------------------------------------------- 1 | # az acr list 2 | ACR_NAME=k8scourse 3 | EMAIL=erick.speaker@hotmail.com 4 | PASS=$(az acr credential show -n $ACR_NAME --query "passwords[0].value") 5 | PASS=${PASS//\"} 6 | 7 | ACR_USERNAME=$(az acr credential show -n $ACR_NAME --query "username") 8 | ACR_USERNAME=${ACR_USERNAME//\"} 9 | SECRET_NAME=acr-credentials 10 | 11 | 12 | 13 | kubectl delete secret $SECRET_NAME 14 | kubectl create secret docker-registry $SECRET_NAME \ 15 | --docker-server=$ACR_NAME.azurecr.io \ 16 | --docker-username=$ACR_NAME \ 17 | --docker-password=$PASS \ 18 | --docker-email=$EMAIL 19 | 20 | kubectl get secret acr-credentials -o json > docker-registry-secret.json 21 | 22 | kubectl delete -f heroes-pod.json 23 | 24 | kubectl create -f heroes-pod.json 25 | kubectl expose -f heroes-pod.json --port 4000 --type=LoadBalancer 26 | 27 | 28 | echo -n $ACR_USERNAME | base64 29 | echo -n $PASS | base64 30 | 31 | kubectl create -f secret.json 32 | 33 | echo 'MWYyZDFlMmU2N2Rm' | base64 --decode 34 | -------------------------------------------------------------------------------- /module-06 - secrets/docker-registry-secret.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | ".dockerconfigjson": "eyJhdXRocyI6eyJrOHNjb3Vyc2UuYXp1cmVjci5pbyI6eyJ1c2VybmFtZSI6Ims4c2NvdXJzZSIsInBhc3N3b3JkIjoiWDJzVDFIZnYxVzJBVmhoTkplbXdoUT1wajhzWEEwaWciLCJlbWFpbCI6ImVyaWNrLnNwZWFrZXJAaG90bWFpbC5jb20iLCJhdXRoIjoiYXpoelkyOTFjbk5sT2xneWMxUXhTR1oyTVZjeVFWWm9hRTVLWlcxM2FGRTljR280YzFoQk1HbG4ifX19" 5 | }, 6 | "kind": "Secret", 7 | "metadata": { 8 | "creationTimestamp": "2018-04-29T19:49:57Z", 9 | "name": "acr-credentials", 10 | "namespace": "production", 11 | "resourceVersion": "281659", 12 | "selfLink": "/api/v1/namespaces/production/secrets/acr-credentials", 13 | "uid": "7e87e89f-4be6-11e8-a25b-0a58ac1f1167" 14 | }, 15 | "type": "kubernetes.io/dockerconfigjson" 16 | } 17 | -------------------------------------------------------------------------------- /module-06 - secrets/heroes-pod.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Pod", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "zone": "prod", 8 | "version": "v1" 9 | } 10 | }, 11 | "spec": { 12 | "containers": [{ 13 | "name": "api-heroes", 14 | "image": "k8scourse.azurecr.io/api-heroes", 15 | "ports": [{ 16 | "containerPort": 4000 17 | }], 18 | "env": [{ 19 | "name": "MONGO_URL", 20 | "value": "10.244.0.109" 21 | }, { 22 | "name": "PORT", 23 | "value": "4000" 24 | }] 25 | }], 26 | 27 | "imagePullSecrets": [{ 28 | "name": "acr-credentials" 29 | }], 30 | "restartPolicy": "Always" 31 | } 32 | } -------------------------------------------------------------------------------- /module-06 - secrets/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysecret 5 | type: Opaque 6 | data: 7 | username: YWRtaW4= 8 | password: MWYyZDFlMmU2N2Rm -------------------------------------------------------------------------------- /module-07 - replicaSets/heroes-rs.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "ReplicaSet", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "app": "api-heroes", 8 | "version": "v1" 9 | } 10 | }, 11 | "spec": { 12 | "replicas": 10, 13 | "selector": { 14 | "matchLabels": { 15 | "version": "v1", 16 | "app": "api-heroes" 17 | } 18 | }, 19 | "template": { 20 | "metadata": { 21 | "labels": { 22 | "version": "v1", 23 | "app": "api-heroes" 24 | } 25 | }, 26 | "spec": { 27 | "containers": [{ 28 | "name": "api-heroes", 29 | "image": "k8scourse.azurecr.io/api-heroes", 30 | 31 | "ports": [{ 32 | "containerPort": 4000 33 | }], 34 | "env": [{ 35 | "name": "MONGO_URL", 36 | "value": "10.244.0.109" 37 | }, { 38 | "name": "PORT", 39 | "value": "4000" 40 | }] 41 | }], 42 | "imagePullSecrets": [{ 43 | "name": "acr-credentials" 44 | }] 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /module-07 - replicaSets/working with replicaSets.sh: -------------------------------------------------------------------------------- 1 | kubectl create -f heroes-rc.json 2 | 3 | kubectl describe rc api-heroes-rc 4 | 5 | kubectl expose -f heroes-rs.json --port=4000 --type=LoadBalancer 6 | 7 | kubectl -------------------------------------------------------------------------------- /module-08 - services/heroes-pod.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Pod", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "zone": "prod", 8 | "version": "v1", 9 | "app": "api-heroes" 10 | 11 | } 12 | }, 13 | "spec": { 14 | "containers": [{ 15 | "name": "api-heroes", 16 | "image": "k8scourse.azurecr.io/api-heroes", 17 | "ports": [{ 18 | "containerPort": 4000 19 | }], 20 | "env": [{ 21 | "name": "MONGO_URL", 22 | "value": "mongodb-svc" 23 | }, { 24 | 25 | "name": "PORT", 26 | "value": "4000" 27 | 28 | }] 29 | }], 30 | "imagePullSecrets": [{ 31 | "name": "acr-credentials" 32 | }] 33 | } 34 | } -------------------------------------------------------------------------------- /module-08 - services/heroes-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "api-heroes-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | 10 | } 11 | }, 12 | "spec": { 13 | "selector": { 14 | "app": "api-heroes" 15 | 16 | }, 17 | "type": "LoadBalancer", 18 | "ports": [{ 19 | "protocol": "TCP", 20 | "port": 4000, 21 | "targetPort": 4000 22 | }] 23 | } 24 | } -------------------------------------------------------------------------------- /module-08 - services/mongodb-pod.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Pod", 4 | "metadata": { 5 | "name": "mongodb", 6 | "labels": { 7 | "zone": "prod", 8 | "version": "v1", 9 | "app": "mongodb" 10 | } 11 | }, 12 | "spec": { 13 | "containers": [{ 14 | "name": "mongodb", 15 | "image": "mongo:3.5", 16 | "ports": [{ 17 | "containerPort": 27017 18 | }] 19 | }] 20 | } 21 | } -------------------------------------------------------------------------------- /module-08 - services/mongodb-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "mongodb-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "mongodb" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "mongodb" 14 | 15 | }, 16 | "type": "LoadBalancer", 17 | "ports": [{ 18 | "protocol": "TCP", 19 | "port": 27017, 20 | "targetPort": 27017 21 | }] 22 | } 23 | } -------------------------------------------------------------------------------- /module-08 - services/scripts.sh: -------------------------------------------------------------------------------- 1 | kubectl create -f heroes-pod.json 2 | kubectl create -f heroes-svc.json 3 | 4 | kubectl create -f mongodb-pod.json 5 | kubectl create -f mongodb-svc.json 6 | 7 | kubectl get services -w 8 | 9 | mongo 52.170.146.14 10 | show dbs 11 | #insert 12 | show dbs 13 | 14 | use heroes 15 | show collections 16 | db.hero.find().pretty() -------------------------------------------------------------------------------- /module-09 - deployments/README.md: -------------------------------------------------------------------------------- 1 | # Use cases 2 | 3 | Create a Deployment to rollout a ReplicaSet. The ReplicaSet creates Pods in the background. Check the status of the rollout to see if it succeeds or not. 4 | 5 | Declare the new state of the Pods by updating the PodTemplateSpec of the Deployment. A new ReplicaSet is created and the Deployment manages moving the Pods from the old ReplicaSet to the new one at a controlled rate. Each new ReplicaSet updates the revision of the Deployment. 6 | 7 | Rollback to an earlier Deployment revision if the current state of the Deployment is not stable. Each rollback updates the revision of the Deployment. 8 | 9 | Scale up the Deployment to facilitate more load. 10 | 11 | Pause the Deployment to apply multiple fixes to its PodTemplateSpec and then resume it to start a new rollout. 12 | 13 | Use the status of the Deployment as an indicator that a rollout has stuck. 14 | 15 | Clean up older ReplicaSets that you don’t need anymore. 16 | -------------------------------------------------------------------------------- /module-09 - deployments/heroes-deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | } 10 | }, 11 | "spec": { 12 | "replicas": 3, 13 | "selector": { 14 | "matchLabels": { 15 | "version": "v1", 16 | "app": "api-heroes" 17 | } 18 | }, 19 | "template": { 20 | "metadata": { 21 | "labels": { 22 | "version": "v1", 23 | "app": "api-heroes" 24 | } 25 | }, 26 | "spec": { 27 | "containers": [ 28 | { 29 | "name": "api-heroes", 30 | "image": "k8simagens.azurecr.io/api-heroes", 31 | "ports": [ 32 | { 33 | "containerPort": 4000 34 | } 35 | ], 36 | "env": [ 37 | { 38 | "name": "MONGO_URL", 39 | "value": "mongodb-svc" 40 | }, 41 | { 42 | "name": "PORT", 43 | "value": "4000" 44 | } 45 | ] 46 | } 47 | ], 48 | "imagePullSecrets": [ 49 | { 50 | "name": "acr-credentials" 51 | } 52 | ] 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /module-09 - deployments/heroes-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "api-heroes-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "api-heroes", 14 | "version": "v1" 15 | }, 16 | "type": "LoadBalancer", 17 | "ports": [ 18 | { 19 | "protocol": "TCP", 20 | "port": 4000 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /module-09 - deployments/mongodb-deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "mongodb-deployment", 6 | "labels": { 7 | "version": "v1", 8 | "app": "mongodb" 9 | } 10 | }, 11 | "spec": { 12 | "replicas": 1, 13 | "selector": { 14 | "matchLabels": { 15 | "version": "v1", 16 | "app": "mongodb" 17 | } 18 | }, 19 | "template": { 20 | "metadata": { 21 | "labels": { 22 | "version": "v1", 23 | "app": "mongodb" 24 | } 25 | }, 26 | "spec": { 27 | "containers": [ 28 | { 29 | "name": "mongodb", 30 | "image": "mongo:3.5", 31 | "ports": [ 32 | { 33 | "containerPort": 27017 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /module-09 - deployments/mongodb-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "mongodb-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "mongodb" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "mongodb", 14 | "version": "v1" 15 | }, 16 | "type": "LoadBalancer", 17 | "ports": [{ 18 | "protocol": "TCP", 19 | "port": 27017 20 | }] 21 | } 22 | } -------------------------------------------------------------------------------- /module-09 - deployments/scripts.sh: -------------------------------------------------------------------------------- 1 | siege -c255 -t120S --content-type "application/json" 'http://52.170.135.165:4000/heroes POST { "name": "Batman", "power": "Inteligencia"}' 2 | 3 | kubectl delete pod -l app=api-heroes -------------------------------------------------------------------------------- /module-10 - rolling updates/heroes-deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | } 10 | }, 11 | "spec": { 12 | "replicas": 2, 13 | "strategy": { 14 | "type": "RollingUpdate", 15 | "rollingUpdate": { 16 | "maxSurge": 1, 17 | "maxUnavailable": 1 18 | } 19 | }, 20 | "minReadySeconds": 5, 21 | "selector": { 22 | "matchLabels": { 23 | "version": "v1", 24 | "app": "api-heroes" 25 | } 26 | }, 27 | "template": { 28 | "metadata": { 29 | "labels": { 30 | "version": "v1", 31 | "app": "api-heroes" 32 | } 33 | }, 34 | "spec": { 35 | "containers": [ 36 | { 37 | "name": "api-heroes", 38 | "image": "k8scourse.azurecr.io/api-heroes:3", 39 | "ports": [ 40 | { 41 | "containerPort": 4000 42 | } 43 | ], 44 | "env": [ 45 | { 46 | "name": "MONGO_URL", 47 | "value": "mongodb-svc" 48 | }, 49 | { 50 | "name": "PORT", 51 | "value": "4000" 52 | } 53 | ], 54 | "resources": { 55 | "requests": { 56 | "memory": "64Mi", 57 | "cpu": "250m" 58 | }, 59 | "limits": { 60 | "memory": "100Mi", 61 | "cpu": "500m" 62 | } 63 | } 64 | } 65 | ], 66 | "imagePullSecrets": [ 67 | { 68 | "name": "acr-credentials" 69 | } 70 | ] 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | ADD . /src 4 | 5 | WORKDIR /src 6 | 7 | RUN npm i -g typescript 8 | 9 | RUN npm i 10 | 11 | RUN npm run build 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/README.md: -------------------------------------------------------------------------------- 1 | ## Node.js with MongoDB Example 2 | 3 | Swagger Page of that application 4 | 5 | ### Requirements 6 | 7 | * Node.js v7+ 8 | * MongoDB running on local instance 9 | 10 | ### Running 11 | 12 | * Install dependencies - `npm i` 13 | * Build typescript - `npm run build` 14 | * Run project - `npm start` 15 | * Go to swagger page - `localhost:3000/documentation` 16 | -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | api-heroes: 4 | # build: . 5 | image: erickwendel/api-heroes 6 | ports: 7 | - 3000:3000 8 | environment: 9 | MONGO_URL: mongodb 10 | links: 11 | - mongodb 12 | 13 | mongodb: 14 | image: mongo:3.5 15 | ports: 16 | - 27017:2017 -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/index.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from "hapi"; 2 | import * as Joi from "joi"; 3 | import { MongoClient } from "mongodb"; 4 | 5 | const Inert = require("inert"); 6 | const Vision = require("vision"); 7 | const HapiSwagger = require("hapi-swagger"); 8 | const server = new Hapi.Server(); 9 | const port = process.env.PORT || 3000; 10 | server.connection({ port }); 11 | 12 | (async () => { 13 | const connectionString = `mongodb://${process.env.MONGO_URL || 14 | "localhost"}/heroes`; 15 | const connection = await MongoClient.connect(connectionString); 16 | console.log("mongo db is running"); 17 | const db = connection.db("heroes").collection("hero"); 18 | await server.register([ 19 | Inert, 20 | Vision, 21 | { 22 | register: HapiSwagger, 23 | options: { 24 | info: { 25 | title: "V3 Node.js with MongoDB Example - Erick Wendel - Updated", 26 | version: "3.0", 27 | }, 28 | }, 29 | }, 30 | ]); 31 | 32 | server.route([ 33 | { 34 | method: "GET", 35 | path: "/heroes", 36 | config: { 37 | handler: (req: any, reply: any) => { 38 | return reply(db.find().toArray()); 39 | }, 40 | description: "List All heroes", 41 | notes: "heroes from database", 42 | tags: ["api"], 43 | }, 44 | }, 45 | { 46 | method: "POST", 47 | path: "/heroes", 48 | config: { 49 | handler: (req, reply) => { 50 | const { payload } = req; 51 | return reply(db.insert(payload)); 52 | }, 53 | description: "Create a hero", 54 | notes: "create a hero", 55 | tags: ["api"], 56 | validate: { 57 | payload: { 58 | name: Joi.string().required(), 59 | power: Joi.string().required(), 60 | }, 61 | }, 62 | }, 63 | }, 64 | 65 | { 66 | method: "DELETE", 67 | path: "/heroes/{id}", 68 | config: { 69 | handler: (req, reply) => { 70 | return reply(db.remove({ _id: req.params.id })); 71 | }, 72 | description: "Delete a hero", 73 | notes: "Delete a hero", 74 | tags: ["api"], 75 | validate: { 76 | params: { 77 | id: Joi.string().required(), 78 | }, 79 | }, 80 | }, 81 | }, 82 | ]); 83 | 84 | await server.start(); 85 | console.log("server running at", port); 86 | })(); 87 | -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "preinstall": "npm i -g typescript", 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "start": "node lib/index.js", 10 | "build": "tsc" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@types/hapi": "^15.0.2", 17 | "@types/joi": "^13.0.5", 18 | "@types/mongodb": "^3.0.5", 19 | "hapi": "^15.2.0", 20 | "hapi-swagger": "^7.10.0", 21 | "inert": "^4.2.1", 22 | "joi": "^13.1.2", 23 | "mongodb": "^3.0.3", 24 | "vision": "^4.1.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /module-10 - rolling updates/nodejs-with-mongodb-api-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": 5 | "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */, 6 | "module": 7 | "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 8 | "lib": [ 9 | "es2015" 10 | ] /* Specify library files to be included in the compilation: */, 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "lib" /* Redirect output structure to the directory. */, 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": false /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 31 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 32 | 33 | /* Additional Checks */ 34 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 35 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 36 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 37 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 38 | 39 | /* Module Resolution Options */ 40 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 41 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 42 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 43 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 44 | // "typeRoots": [], /* List of folders to include type definitions from. */ 45 | // "types": [], /* Type declaration files to be included in compilation. */ 46 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 47 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 48 | 49 | /* Source Map Options */ 50 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 51 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 52 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 53 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 54 | 55 | /* Experimental Options */ 56 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 57 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /module-10 - rolling updates/scripts.sh: -------------------------------------------------------------------------------- 1 | 2 | kubectl create -f nginx.yaml 3 | kubectl get deployment 4 | 5 | # "spec": { 6 | # "replicas": 3, 7 | # "selector": { 8 | # "matchLabels": { 9 | # "version": "v1", 10 | # "app": "api-heroes" 11 | # } 12 | # }, 13 | kubectl apply -f heroes-deploy.json --record 14 | kubectl get deploy api-heroes 15 | kubectl rollout history deployment api-heroes 16 | kubectl rollout status deployment api-heroes 17 | kubectl rollout undo deployment api-heroes --to-revision=1 18 | kubectl set image deployment api-heroes api-heroes=k8scourse.azurecr.io/api-heroes:3 --record 19 | 20 | kubectl replace -f heroes-deploy.json --record 21 | kubectl edit deployment api-heroes --record 22 | 23 | kubectl rollout pause deployment api-heroes 24 | kubectl rollout resume deployment api-heroes 25 | -------------------------------------------------------------------------------- /module-11 - ingress controllers/1. nginx-default-backend.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: nginx-default-backend 5 | spec: 6 | ports: 7 | - port: 80 8 | targetPort: http 9 | selector: 10 | app: nginx-default-backend 11 | --- 12 | kind: Deployment 13 | apiVersion: extensions/v1beta1 14 | metadata: 15 | name: nginx-default-backend 16 | spec: 17 | replicas: 1 18 | template: 19 | metadata: 20 | labels: 21 | app: nginx-default-backend 22 | spec: 23 | terminationGracePeriodSeconds: 60 24 | containers: 25 | - name: default-http-backend 26 | image: gcr.io/google_containers/defaultbackend:1.0 27 | livenessProbe: 28 | httpGet: 29 | path: /healthz 30 | port: 8080 31 | scheme: HTTP 32 | initialDelaySeconds: 30 33 | timeoutSeconds: 5 34 | ports: 35 | - containerPort: 8080 -------------------------------------------------------------------------------- /module-11 - ingress controllers/2. ingress-controller-nginx.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: ingress-nginx 5 | spec: 6 | type: LoadBalancer 7 | selector: 8 | app: ingress-nginx 9 | ports: 10 | - port: 80 11 | --- 12 | kind: Deployment 13 | apiVersion: extensions/v1beta1 14 | metadata: 15 | name: ingress-nginx 16 | spec: 17 | replicas: 1 18 | template: 19 | metadata: 20 | labels: 21 | app: ingress-nginx 22 | spec: 23 | terminationGracePeriodSeconds: 60 24 | containers: 25 | - image: gcr.io/google_containers/nginx-ingress-controller:0.8.3 26 | name: ingress-nginx 27 | imagePullPolicy: Always 28 | ports: 29 | - containerPort: 80 30 | 31 | livenessProbe: 32 | httpGet: 33 | path: /healthz 34 | port: 10254 35 | scheme: HTTP 36 | initialDelaySeconds: 30 37 | timeoutSeconds: 5 38 | env: 39 | - name: POD_NAME 40 | valueFrom: 41 | fieldRef: 42 | fieldPath: metadata.name 43 | - name: POD_NAMESPACE 44 | valueFrom: 45 | fieldRef: 46 | fieldPath: metadata.namespace 47 | args: 48 | - /nginx-ingress-controller 49 | - --default-backend-service=$(POD_NAMESPACE)/nginx-default-backend -------------------------------------------------------------------------------- /module-11 - ingress controllers/3. nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | spec: 6 | ports: 7 | - port: 80 8 | targetPort: 80 9 | selector: 10 | app: nginx 11 | --- 12 | apiVersion: extensions/v1beta1 13 | kind: Deployment 14 | metadata: 15 | name: nginx 16 | spec: 17 | replicas: 1 18 | template: 19 | metadata: 20 | labels: 21 | app: nginx 22 | spec: 23 | containers: 24 | - name: echoserver 25 | image: nginx 26 | ports: 27 | - containerPort: 80 -------------------------------------------------------------------------------- /module-11 - ingress controllers/4. demo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: demo-ingress 5 | spec: 6 | rules: 7 | - http: 8 | paths: 9 | - path: / 10 | backend: 11 | serviceName: api-heroes-svc 12 | servicePort: 4000 13 | 14 | - host: mysite.com 15 | http: 16 | paths: 17 | - path: / 18 | backend: 19 | serviceName: nginx 20 | servicePort: 80 -------------------------------------------------------------------------------- /module-11 - ingress controllers/script.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | curl -H 'Host:mysite.com' 104.45.150.226 4 | curl -H 'Host:api.com' 52.234.231.127 -------------------------------------------------------------------------------- /module-12 - statefulSet/mongodb.stateful.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "apps/v1beta1", 3 | "kind": "StatefulSet", 4 | "metadata": { 5 | "name": "mongodb", 6 | "labels": { 7 | "app": "mongodb" 8 | } 9 | }, 10 | "spec": { 11 | "serviceName": "mongosvc", 12 | "replicas": 2, 13 | "volumeClaimTemplates": [ 14 | { 15 | "metadata": { 16 | "name": "azurefile" 17 | }, 18 | "spec": { 19 | "storageClassName": "default", 20 | "accessModes": ["ReadWriteOnce"], 21 | "resources": { 22 | "requests": { 23 | "storage": "5Gi" 24 | } 25 | } 26 | } 27 | } 28 | ], 29 | "template": { 30 | "metadata": { 31 | "labels": { 32 | "app": "mongodb" 33 | } 34 | }, 35 | 36 | "spec": { 37 | "containers": [ 38 | { 39 | "name": "mongodb", 40 | "image": "mongo:3.5", 41 | "ports": [ 42 | { 43 | "containerPort": 27017, 44 | "name": "mongodb" 45 | } 46 | ], 47 | "volumeMounts": [ 48 | { 49 | "mountPath": "/data/db", 50 | "name": "azurefile" 51 | } 52 | ] 53 | } 54 | ] 55 | } 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /module-13 - volumes/1. persistent-volume.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "PersistentVolume", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "uploads-pv", 6 | "labels": { 7 | "type": "local" 8 | } 9 | }, 10 | "spec": { 11 | "storageClassName": "default", 12 | "capacity": { 13 | "storage": "5Gi" 14 | }, 15 | "accessModes": ["ReadWriteOnce"], 16 | "hostPath": { 17 | "path": "/src/uploads" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /module-13 - volumes/2. persistent-volume-claim.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "PersistentVolumeClaim", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "uploads-pvc" 6 | }, 7 | "spec": { 8 | "storageClassName": "default", 9 | "accessModes": ["ReadWriteOnce"], 10 | "resources": { 11 | "requests": { 12 | "storage": "5Gi" 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /module-13 - volumes/3. upload-app.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "upload-app-deployment", 6 | "labels": { 7 | 8 | "app": "upload-app" 9 | } 10 | }, 11 | "spec": { 12 | "replicas": 1, 13 | "selector": { 14 | "matchLabels": { 15 | 16 | "app": "upload-app" 17 | } 18 | }, 19 | "template": { 20 | "metadata": { 21 | "labels": { 22 | 23 | "app": "upload-app" 24 | } 25 | }, 26 | "spec": { 27 | "containers": [{ 28 | 29 | "name": "upload-app", 30 | "image": "erickwendel/k8s-upload-example-nodejs", 31 | "volumeMounts": [{ 32 | "name": "uploads", 33 | "mountPath": "/src/uploads" 34 | }], 35 | "ports": [{ 36 | "containerPort": 3000 37 | }] 38 | 39 | }], 40 | "volumes": [{ 41 | "name": "uploads", 42 | "persistentVolumeClaim": { 43 | "claimName": "uploads-pvc" 44 | } 45 | }] 46 | 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /module-13 - volumes/scripts.sh: -------------------------------------------------------------------------------- 1 | # emptyDir #usado somente para dados temporário, quando um pod morre, ele perde todos os dados 2 | 3 | kubectl create -f 1.\ persistent-volume.json \ 4 | -f 2.\ persistent-volume-claim.json \ 5 | -f 3.\ upload-app.json 6 | 7 | 8 | kubectl expose -f 3.\ upload-app.json --type LoadBalancer --port 3000 9 | -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | package-lock.json -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | ADD . /src 4 | 5 | WORKDIR /src 6 | 7 | RUN npm i -g typescript pm2 --production --silent 8 | 9 | RUN npm i --production --silent 10 | 11 | RUN npm run build 12 | 13 | CMD npm start -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/Index.ts: -------------------------------------------------------------------------------- 1 | 2 | import { MongoClient } from "mongodb"; 3 | 4 | import request from "request-promise" 5 | const connectionString = `mongodb://${process.env.MONGO_URL || "localhost:27017"}`; 6 | 7 | (async () => { 8 | console.log('connectionString', connectionString) 9 | const connection = await MongoClient.connect(connectionString); 10 | console.log("mongo db is running"); 11 | const db = connection.db("heroes").collection("people"); 12 | await db.remove({}) 13 | 14 | const promises = [] 15 | for (let i = 1; i <= 100; i++) { 16 | try { 17 | 18 | const url = `https://swapi.co/api/people/${i}`; 19 | console.log('trying', url) 20 | const results = await request(url) 21 | const data = JSON.parse(results) 22 | console.log(`name ${data.name}`) 23 | const item = Object.assign({}, data, { index: i, insertedAt: new Date() }) 24 | promises.push(db.insert(item)) 25 | } 26 | catch (e) { 27 | if (e.statusCode === 404) break; 28 | 29 | throw e 30 | } 31 | } 32 | await Promise.all(promises) 33 | console.log('job finished'); 34 | process.exit(0); 35 | })(); 36 | -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | job: 4 | build: . 5 | environment: 6 | MONGO_URL: mongodb 7 | links: 8 | - mongodb 9 | 10 | mongodb: 11 | image: mongo:3.5 12 | ports: 13 | - 27017:2017 -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "job-example", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/bluebird": { 8 | "version": "3.5.20", 9 | "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.20.tgz", 10 | "integrity": "sha512-Wk41MVdF+cHBfVXj/ufUHJeO3BlIQr1McbHZANErMykaCWeDSZbH5erGjNBw2/3UlRdSxZbLfSuQTzFmPOYFsA==" 11 | }, 12 | "@types/bson": { 13 | "version": "1.0.8", 14 | "resolved": "https://registry.npmjs.org/@types/bson/-/bson-1.0.8.tgz", 15 | "integrity": "sha512-PMa4nkRhLaqwsXQDDTzGbTyCIpej0ERznyAP9fyuGnlsmUbcC4Y25mdqjibYjkOPNyK/BWWUKneruaKHcS3Q8g==", 16 | "requires": { 17 | "@types/node": "10.0.0" 18 | } 19 | }, 20 | "@types/caseless": { 21 | "version": "0.12.1", 22 | "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz", 23 | "integrity": "sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A==" 24 | }, 25 | "@types/events": { 26 | "version": "1.2.0", 27 | "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", 28 | "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" 29 | }, 30 | "@types/form-data": { 31 | "version": "2.2.1", 32 | "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", 33 | "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", 34 | "requires": { 35 | "@types/node": "10.0.0" 36 | } 37 | }, 38 | "@types/mongodb": { 39 | "version": "3.0.15", 40 | "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.0.15.tgz", 41 | "integrity": "sha512-sc96v9z3S3dS7acW6q6eKnAEvU2X3a42RIAslNAGpKpjy9Kw/M4dZfUtf83+mUNRM7OUejMIb/UP46OhIH+lYA==", 42 | "requires": { 43 | "@types/bson": "1.0.8", 44 | "@types/events": "1.2.0", 45 | "@types/node": "10.0.0" 46 | } 47 | }, 48 | "@types/node": { 49 | "version": "10.0.0", 50 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.0.0.tgz", 51 | "integrity": "sha512-kctoM36XiNZT86a7tPsUje+Q/yl+dqELjtYApi0T5eOQ90Elhu0MI10rmYk44yEP4v1jdDvtjQ9DFtpRtHf2Bw==" 52 | }, 53 | "@types/request": { 54 | "version": "2.47.0", 55 | "resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.0.tgz", 56 | "integrity": "sha512-/KXM5oev+nNCLIgBjkwbk8VqxmzI56woD4VUxn95O+YeQ8hJzcSmIZ1IN3WexiqBb6srzDo2bdMbsXxgXNkz5Q==", 57 | "requires": { 58 | "@types/caseless": "0.12.1", 59 | "@types/form-data": "2.2.1", 60 | "@types/node": "10.0.0", 61 | "@types/tough-cookie": "2.3.2" 62 | } 63 | }, 64 | "@types/request-promise": { 65 | "version": "4.1.41", 66 | "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.41.tgz", 67 | "integrity": "sha512-qlx6COxSTdSFHY9oX9v2zL1I05hgz5lwqYiXa2SFL2nDxAiG5KK8rnllLBH7k6OqzS3Ck0bWbxlGVdrZhS6oNw==", 68 | "requires": { 69 | "@types/bluebird": "3.5.20", 70 | "@types/request": "2.47.0" 71 | } 72 | }, 73 | "@types/tough-cookie": { 74 | "version": "2.3.2", 75 | "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.2.tgz", 76 | "integrity": "sha512-vOVmaruQG5EatOU/jM6yU2uCp3Lz6mK1P5Ztu4iJjfM4SVHU9XYktPUQtKlIXuahqXHdEyUarMrBEwg5Cwu+bA==" 77 | }, 78 | "ajv": { 79 | "version": "5.5.2", 80 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 81 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 82 | "requires": { 83 | "co": "4.6.0", 84 | "fast-deep-equal": "1.1.0", 85 | "fast-json-stable-stringify": "2.0.0", 86 | "json-schema-traverse": "0.3.1" 87 | } 88 | }, 89 | "ansi-styles": { 90 | "version": "3.2.1", 91 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 92 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 93 | "requires": { 94 | "color-convert": "1.9.1" 95 | } 96 | }, 97 | "array-find-index": { 98 | "version": "1.0.2", 99 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", 100 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" 101 | }, 102 | "arrify": { 103 | "version": "1.0.1", 104 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 105 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" 106 | }, 107 | "asn1": { 108 | "version": "0.2.3", 109 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 110 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" 111 | }, 112 | "assert-plus": { 113 | "version": "1.0.0", 114 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 115 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 116 | }, 117 | "asynckit": { 118 | "version": "0.4.0", 119 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 120 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 121 | }, 122 | "aws-sign2": { 123 | "version": "0.7.0", 124 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 125 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 126 | }, 127 | "aws4": { 128 | "version": "1.7.0", 129 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", 130 | "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" 131 | }, 132 | "bcrypt-pbkdf": { 133 | "version": "1.0.1", 134 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 135 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", 136 | "optional": true, 137 | "requires": { 138 | "tweetnacl": "0.14.5" 139 | } 140 | }, 141 | "bluebird": { 142 | "version": "3.5.1", 143 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 144 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 145 | }, 146 | "boom": { 147 | "version": "4.3.1", 148 | "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", 149 | "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", 150 | "requires": { 151 | "hoek": "4.2.1" 152 | } 153 | }, 154 | "bson": { 155 | "version": "1.0.6", 156 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", 157 | "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" 158 | }, 159 | "builtin-modules": { 160 | "version": "1.1.1", 161 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 162 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 163 | }, 164 | "camelcase": { 165 | "version": "4.1.0", 166 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 167 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 168 | }, 169 | "camelcase-keys": { 170 | "version": "4.2.0", 171 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", 172 | "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", 173 | "requires": { 174 | "camelcase": "4.1.0", 175 | "map-obj": "2.0.0", 176 | "quick-lru": "1.1.0" 177 | } 178 | }, 179 | "caseless": { 180 | "version": "0.12.0", 181 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 182 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 183 | }, 184 | "chalk": { 185 | "version": "2.4.1", 186 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 187 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 188 | "requires": { 189 | "ansi-styles": "3.2.1", 190 | "escape-string-regexp": "1.0.5", 191 | "supports-color": "5.4.0" 192 | } 193 | }, 194 | "chalk-animation": { 195 | "version": "1.6.0", 196 | "resolved": "https://registry.npmjs.org/chalk-animation/-/chalk-animation-1.6.0.tgz", 197 | "integrity": "sha512-Q8vVq6eD5IOhWI0s9WdUawDzMRjNrR4rOCiu409eZRTIHID5OjoTTEkpGZngL/BPQnL7yYmBhlXXpPJ9SYuARw==", 198 | "requires": { 199 | "chalk": "2.4.1", 200 | "gradient-string": "1.1.0", 201 | "meow": "4.0.1" 202 | } 203 | }, 204 | "co": { 205 | "version": "4.6.0", 206 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 207 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 208 | }, 209 | "color-convert": { 210 | "version": "1.9.1", 211 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 212 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 213 | "requires": { 214 | "color-name": "1.1.3" 215 | } 216 | }, 217 | "color-name": { 218 | "version": "1.1.3", 219 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 220 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 221 | }, 222 | "combined-stream": { 223 | "version": "1.0.6", 224 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 225 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 226 | "requires": { 227 | "delayed-stream": "1.0.0" 228 | } 229 | }, 230 | "core-util-is": { 231 | "version": "1.0.2", 232 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 233 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 234 | }, 235 | "cryptiles": { 236 | "version": "3.1.2", 237 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", 238 | "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", 239 | "requires": { 240 | "boom": "5.2.0" 241 | }, 242 | "dependencies": { 243 | "boom": { 244 | "version": "5.2.0", 245 | "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", 246 | "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", 247 | "requires": { 248 | "hoek": "4.2.1" 249 | } 250 | } 251 | } 252 | }, 253 | "currently-unhandled": { 254 | "version": "0.4.1", 255 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", 256 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", 257 | "requires": { 258 | "array-find-index": "1.0.2" 259 | } 260 | }, 261 | "dashdash": { 262 | "version": "1.14.1", 263 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 264 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 265 | "requires": { 266 | "assert-plus": "1.0.0" 267 | } 268 | }, 269 | "decamelize": { 270 | "version": "1.2.0", 271 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 272 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 273 | }, 274 | "decamelize-keys": { 275 | "version": "1.1.0", 276 | "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", 277 | "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", 278 | "requires": { 279 | "decamelize": "1.2.0", 280 | "map-obj": "1.0.1" 281 | }, 282 | "dependencies": { 283 | "map-obj": { 284 | "version": "1.0.1", 285 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 286 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" 287 | } 288 | } 289 | }, 290 | "delayed-stream": { 291 | "version": "1.0.0", 292 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 293 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 294 | }, 295 | "ecc-jsbn": { 296 | "version": "0.1.1", 297 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 298 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 299 | "optional": true, 300 | "requires": { 301 | "jsbn": "0.1.1" 302 | } 303 | }, 304 | "error-ex": { 305 | "version": "1.3.1", 306 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 307 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 308 | "requires": { 309 | "is-arrayish": "0.2.1" 310 | } 311 | }, 312 | "escape-string-regexp": { 313 | "version": "1.0.5", 314 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 315 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 316 | }, 317 | "extend": { 318 | "version": "3.0.1", 319 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 320 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" 321 | }, 322 | "extsprintf": { 323 | "version": "1.3.0", 324 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 325 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 326 | }, 327 | "fast-deep-equal": { 328 | "version": "1.1.0", 329 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 330 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 331 | }, 332 | "fast-json-stable-stringify": { 333 | "version": "2.0.0", 334 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 335 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 336 | }, 337 | "find-up": { 338 | "version": "2.1.0", 339 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 340 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 341 | "requires": { 342 | "locate-path": "2.0.0" 343 | } 344 | }, 345 | "forever-agent": { 346 | "version": "0.6.1", 347 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 348 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 349 | }, 350 | "form-data": { 351 | "version": "2.3.2", 352 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 353 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 354 | "requires": { 355 | "asynckit": "0.4.0", 356 | "combined-stream": "1.0.6", 357 | "mime-types": "2.1.18" 358 | } 359 | }, 360 | "getpass": { 361 | "version": "0.1.7", 362 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 363 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 364 | "requires": { 365 | "assert-plus": "1.0.0" 366 | } 367 | }, 368 | "graceful-fs": { 369 | "version": "4.1.11", 370 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 371 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 372 | }, 373 | "gradient-string": { 374 | "version": "1.1.0", 375 | "resolved": "https://registry.npmjs.org/gradient-string/-/gradient-string-1.1.0.tgz", 376 | "integrity": "sha1-OklIyn/Y9zlqjxlXkYghuaEREsA=", 377 | "requires": { 378 | "chalk": "2.4.1", 379 | "tinygradient": "0.3.1" 380 | } 381 | }, 382 | "har-schema": { 383 | "version": "2.0.0", 384 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 385 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 386 | }, 387 | "har-validator": { 388 | "version": "5.0.3", 389 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", 390 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", 391 | "requires": { 392 | "ajv": "5.5.2", 393 | "har-schema": "2.0.0" 394 | } 395 | }, 396 | "has-flag": { 397 | "version": "3.0.0", 398 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 399 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 400 | }, 401 | "hawk": { 402 | "version": "6.0.2", 403 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", 404 | "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", 405 | "requires": { 406 | "boom": "4.3.1", 407 | "cryptiles": "3.1.2", 408 | "hoek": "4.2.1", 409 | "sntp": "2.1.0" 410 | } 411 | }, 412 | "hoek": { 413 | "version": "4.2.1", 414 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", 415 | "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" 416 | }, 417 | "hosted-git-info": { 418 | "version": "2.6.0", 419 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", 420 | "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==" 421 | }, 422 | "http-signature": { 423 | "version": "1.2.0", 424 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 425 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 426 | "requires": { 427 | "assert-plus": "1.0.0", 428 | "jsprim": "1.4.1", 429 | "sshpk": "1.14.1" 430 | } 431 | }, 432 | "indent-string": { 433 | "version": "3.2.0", 434 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", 435 | "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" 436 | }, 437 | "is-arrayish": { 438 | "version": "0.2.1", 439 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 440 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 441 | }, 442 | "is-builtin-module": { 443 | "version": "1.0.0", 444 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 445 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 446 | "requires": { 447 | "builtin-modules": "1.1.1" 448 | } 449 | }, 450 | "is-plain-obj": { 451 | "version": "1.1.0", 452 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", 453 | "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" 454 | }, 455 | "is-typedarray": { 456 | "version": "1.0.0", 457 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 458 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 459 | }, 460 | "isstream": { 461 | "version": "0.1.2", 462 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 463 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 464 | }, 465 | "jsbn": { 466 | "version": "0.1.1", 467 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 468 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 469 | "optional": true 470 | }, 471 | "json-parse-better-errors": { 472 | "version": "1.0.2", 473 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 474 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" 475 | }, 476 | "json-schema": { 477 | "version": "0.2.3", 478 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 479 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 480 | }, 481 | "json-schema-traverse": { 482 | "version": "0.3.1", 483 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 484 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 485 | }, 486 | "json-stringify-safe": { 487 | "version": "5.0.1", 488 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 489 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 490 | }, 491 | "jsprim": { 492 | "version": "1.4.1", 493 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 494 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 495 | "requires": { 496 | "assert-plus": "1.0.0", 497 | "extsprintf": "1.3.0", 498 | "json-schema": "0.2.3", 499 | "verror": "1.10.0" 500 | } 501 | }, 502 | "load-json-file": { 503 | "version": "4.0.0", 504 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", 505 | "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", 506 | "requires": { 507 | "graceful-fs": "4.1.11", 508 | "parse-json": "4.0.0", 509 | "pify": "3.0.0", 510 | "strip-bom": "3.0.0" 511 | } 512 | }, 513 | "locate-path": { 514 | "version": "2.0.0", 515 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 516 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 517 | "requires": { 518 | "p-locate": "2.0.0", 519 | "path-exists": "3.0.0" 520 | } 521 | }, 522 | "lodash": { 523 | "version": "4.17.10", 524 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", 525 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" 526 | }, 527 | "loud-rejection": { 528 | "version": "1.6.0", 529 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", 530 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", 531 | "requires": { 532 | "currently-unhandled": "0.4.1", 533 | "signal-exit": "3.0.2" 534 | } 535 | }, 536 | "map-obj": { 537 | "version": "2.0.0", 538 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", 539 | "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=" 540 | }, 541 | "meow": { 542 | "version": "4.0.1", 543 | "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", 544 | "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", 545 | "requires": { 546 | "camelcase-keys": "4.2.0", 547 | "decamelize-keys": "1.1.0", 548 | "loud-rejection": "1.6.0", 549 | "minimist": "1.2.0", 550 | "minimist-options": "3.0.2", 551 | "normalize-package-data": "2.4.0", 552 | "read-pkg-up": "3.0.0", 553 | "redent": "2.0.0", 554 | "trim-newlines": "2.0.0" 555 | } 556 | }, 557 | "mime-db": { 558 | "version": "1.33.0", 559 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 560 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" 561 | }, 562 | "mime-types": { 563 | "version": "2.1.18", 564 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 565 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 566 | "requires": { 567 | "mime-db": "1.33.0" 568 | } 569 | }, 570 | "minimist": { 571 | "version": "1.2.0", 572 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 573 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 574 | }, 575 | "minimist-options": { 576 | "version": "3.0.2", 577 | "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", 578 | "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", 579 | "requires": { 580 | "arrify": "1.0.1", 581 | "is-plain-obj": "1.1.0" 582 | } 583 | }, 584 | "mongodb": { 585 | "version": "3.0.7", 586 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.7.tgz", 587 | "integrity": "sha512-n/14kMJEoARXz1qhpNPhUocqy+z5130jhqgEIX1Tsl8UVpHrndQ8et+VmgC4yPK/I8Tcgc93JEMQCHTekBUnNA==", 588 | "requires": { 589 | "mongodb-core": "3.0.7" 590 | } 591 | }, 592 | "mongodb-core": { 593 | "version": "3.0.7", 594 | "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.7.tgz", 595 | "integrity": "sha512-z6YufO7s40wLiv2ssFshqoLS4+Kf+huhHq6KZ7gDArsKNzXYjAwTMnhEIJ9GQ8fIfBGs5tBLNPfbIDoCKGPmOw==", 596 | "requires": { 597 | "bson": "1.0.6", 598 | "require_optional": "1.0.1" 599 | } 600 | }, 601 | "normalize-package-data": { 602 | "version": "2.4.0", 603 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 604 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 605 | "requires": { 606 | "hosted-git-info": "2.6.0", 607 | "is-builtin-module": "1.0.0", 608 | "semver": "5.5.0", 609 | "validate-npm-package-license": "3.0.3" 610 | } 611 | }, 612 | "oauth-sign": { 613 | "version": "0.8.2", 614 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 615 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" 616 | }, 617 | "p-limit": { 618 | "version": "1.2.0", 619 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", 620 | "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", 621 | "requires": { 622 | "p-try": "1.0.0" 623 | } 624 | }, 625 | "p-locate": { 626 | "version": "2.0.0", 627 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 628 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 629 | "requires": { 630 | "p-limit": "1.2.0" 631 | } 632 | }, 633 | "p-try": { 634 | "version": "1.0.0", 635 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 636 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" 637 | }, 638 | "parse-json": { 639 | "version": "4.0.0", 640 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", 641 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", 642 | "requires": { 643 | "error-ex": "1.3.1", 644 | "json-parse-better-errors": "1.0.2" 645 | } 646 | }, 647 | "path-exists": { 648 | "version": "3.0.0", 649 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 650 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 651 | }, 652 | "path-type": { 653 | "version": "3.0.0", 654 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", 655 | "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", 656 | "requires": { 657 | "pify": "3.0.0" 658 | } 659 | }, 660 | "performance-now": { 661 | "version": "2.1.0", 662 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 663 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 664 | }, 665 | "pify": { 666 | "version": "3.0.0", 667 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 668 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 669 | }, 670 | "punycode": { 671 | "version": "1.4.1", 672 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 673 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 674 | }, 675 | "qs": { 676 | "version": "6.5.1", 677 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 678 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" 679 | }, 680 | "quick-lru": { 681 | "version": "1.1.0", 682 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", 683 | "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=" 684 | }, 685 | "read-pkg": { 686 | "version": "3.0.0", 687 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", 688 | "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", 689 | "requires": { 690 | "load-json-file": "4.0.0", 691 | "normalize-package-data": "2.4.0", 692 | "path-type": "3.0.0" 693 | } 694 | }, 695 | "read-pkg-up": { 696 | "version": "3.0.0", 697 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", 698 | "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", 699 | "requires": { 700 | "find-up": "2.1.0", 701 | "read-pkg": "3.0.0" 702 | } 703 | }, 704 | "redent": { 705 | "version": "2.0.0", 706 | "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", 707 | "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", 708 | "requires": { 709 | "indent-string": "3.2.0", 710 | "strip-indent": "2.0.0" 711 | } 712 | }, 713 | "request": { 714 | "version": "2.85.0", 715 | "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", 716 | "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", 717 | "requires": { 718 | "aws-sign2": "0.7.0", 719 | "aws4": "1.7.0", 720 | "caseless": "0.12.0", 721 | "combined-stream": "1.0.6", 722 | "extend": "3.0.1", 723 | "forever-agent": "0.6.1", 724 | "form-data": "2.3.2", 725 | "har-validator": "5.0.3", 726 | "hawk": "6.0.2", 727 | "http-signature": "1.2.0", 728 | "is-typedarray": "1.0.0", 729 | "isstream": "0.1.2", 730 | "json-stringify-safe": "5.0.1", 731 | "mime-types": "2.1.18", 732 | "oauth-sign": "0.8.2", 733 | "performance-now": "2.1.0", 734 | "qs": "6.5.1", 735 | "safe-buffer": "5.1.2", 736 | "stringstream": "0.0.5", 737 | "tough-cookie": "2.3.4", 738 | "tunnel-agent": "0.6.0", 739 | "uuid": "3.2.1" 740 | } 741 | }, 742 | "request-promise": { 743 | "version": "4.2.2", 744 | "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", 745 | "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", 746 | "requires": { 747 | "bluebird": "3.5.1", 748 | "request-promise-core": "1.1.1", 749 | "stealthy-require": "1.1.1", 750 | "tough-cookie": "2.3.4" 751 | } 752 | }, 753 | "request-promise-core": { 754 | "version": "1.1.1", 755 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", 756 | "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", 757 | "requires": { 758 | "lodash": "4.17.10" 759 | } 760 | }, 761 | "require_optional": { 762 | "version": "1.0.1", 763 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 764 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 765 | "requires": { 766 | "resolve-from": "2.0.0", 767 | "semver": "5.5.0" 768 | } 769 | }, 770 | "resolve-from": { 771 | "version": "2.0.0", 772 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 773 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 774 | }, 775 | "safe-buffer": { 776 | "version": "5.1.2", 777 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 778 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 779 | }, 780 | "semver": { 781 | "version": "5.5.0", 782 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 783 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" 784 | }, 785 | "signal-exit": { 786 | "version": "3.0.2", 787 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 788 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 789 | }, 790 | "sntp": { 791 | "version": "2.1.0", 792 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", 793 | "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", 794 | "requires": { 795 | "hoek": "4.2.1" 796 | } 797 | }, 798 | "spdx-correct": { 799 | "version": "3.0.0", 800 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", 801 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", 802 | "requires": { 803 | "spdx-expression-parse": "3.0.0", 804 | "spdx-license-ids": "3.0.0" 805 | } 806 | }, 807 | "spdx-exceptions": { 808 | "version": "2.1.0", 809 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", 810 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" 811 | }, 812 | "spdx-expression-parse": { 813 | "version": "3.0.0", 814 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 815 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 816 | "requires": { 817 | "spdx-exceptions": "2.1.0", 818 | "spdx-license-ids": "3.0.0" 819 | } 820 | }, 821 | "spdx-license-ids": { 822 | "version": "3.0.0", 823 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", 824 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" 825 | }, 826 | "sshpk": { 827 | "version": "1.14.1", 828 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", 829 | "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", 830 | "requires": { 831 | "asn1": "0.2.3", 832 | "assert-plus": "1.0.0", 833 | "bcrypt-pbkdf": "1.0.1", 834 | "dashdash": "1.14.1", 835 | "ecc-jsbn": "0.1.1", 836 | "getpass": "0.1.7", 837 | "jsbn": "0.1.1", 838 | "tweetnacl": "0.14.5" 839 | } 840 | }, 841 | "stealthy-require": { 842 | "version": "1.1.1", 843 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", 844 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" 845 | }, 846 | "stringstream": { 847 | "version": "0.0.5", 848 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 849 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" 850 | }, 851 | "strip-bom": { 852 | "version": "3.0.0", 853 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 854 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" 855 | }, 856 | "strip-indent": { 857 | "version": "2.0.0", 858 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", 859 | "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=" 860 | }, 861 | "supports-color": { 862 | "version": "5.4.0", 863 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 864 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 865 | "requires": { 866 | "has-flag": "3.0.0" 867 | } 868 | }, 869 | "tinycolor2": { 870 | "version": "1.4.1", 871 | "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", 872 | "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" 873 | }, 874 | "tinygradient": { 875 | "version": "0.3.1", 876 | "resolved": "https://registry.npmjs.org/tinygradient/-/tinygradient-0.3.1.tgz", 877 | "integrity": "sha1-LZ5PvjSMSX7RHih6QzaDWz/RECI=", 878 | "requires": { 879 | "tinycolor2": "1.4.1" 880 | } 881 | }, 882 | "tough-cookie": { 883 | "version": "2.3.4", 884 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", 885 | "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", 886 | "requires": { 887 | "punycode": "1.4.1" 888 | } 889 | }, 890 | "trim-newlines": { 891 | "version": "2.0.0", 892 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", 893 | "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=" 894 | }, 895 | "tunnel-agent": { 896 | "version": "0.6.0", 897 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 898 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 899 | "requires": { 900 | "safe-buffer": "5.1.2" 901 | } 902 | }, 903 | "tweetnacl": { 904 | "version": "0.14.5", 905 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 906 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 907 | "optional": true 908 | }, 909 | "uuid": { 910 | "version": "3.2.1", 911 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", 912 | "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" 913 | }, 914 | "validate-npm-package-license": { 915 | "version": "3.0.3", 916 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", 917 | "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", 918 | "requires": { 919 | "spdx-correct": "3.0.0", 920 | "spdx-expression-parse": "3.0.0" 921 | } 922 | }, 923 | "verror": { 924 | "version": "1.10.0", 925 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 926 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 927 | "requires": { 928 | "assert-plus": "1.0.0", 929 | "core-util-is": "1.0.2", 930 | "extsprintf": "1.3.0" 931 | } 932 | } 933 | } 934 | } 935 | -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "job-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "tsc", 9 | "start": "pm2-docker lib/Index.js" 10 | }, 11 | "keywords": [], 12 | "author": "erickwendel", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@types/mongodb": "3.0.15", 16 | "@types/request-promise": "4.1.41", 17 | "chalk-animation": "^1.6.0", 18 | "mongodb": "3.0.7", 19 | "request": "2.85.0", 20 | "request-promise": "4.2.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "es2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ 5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | "lib": [ 7 | "es2015" 8 | ], /* Specify library files to be included in the compilation. */ 9 | // "allowJs": true, /* Allow javascript files to be compiled. */ 10 | // "checkJs": true, /* Report errors in .js files. */ 11 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 12 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 13 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 14 | // "outFile": "./", /* Concatenate and emit output to single file. */ 15 | "outDir": "lib", /* Redirect output structure to the directory. */ 16 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 17 | // "removeComments": true, /* Do not emit comments to output. */ 18 | // "noEmit": true, /* Do not emit outputs. */ 19 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 20 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 21 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 22 | /* Strict Type-Checking Options */ 23 | "strict": true, /* Enable all strict type-checking options. */ 24 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 25 | // "strictNullChecks": true, /* Enable strict null checks. */ 26 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 27 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 28 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 29 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 30 | /* Additional Checks */ 31 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 32 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 33 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 34 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 35 | /* Module Resolution Options */ 36 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 37 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 38 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 39 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 40 | // "typeRoots": [], /* List of folders to include type definitions from. */ 41 | // "types": [], /* Type declaration files to be included in compilation. */ 42 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 43 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 44 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 45 | /* Source Map Options */ 46 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 47 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 48 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 49 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 50 | /* Experimental Options */ 51 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 52 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 53 | } 54 | } -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/1. job/job.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "batch/v1", 3 | "kind": "Job", 4 | "metadata": { 5 | "name": "job-starwars" 6 | }, 7 | "spec": { 8 | "parallelism": 2, 9 | "completions": 5, 10 | 11 | "template": { 12 | "spec": { 13 | "containers": [{ 14 | "name": "job-starwars", 15 | "image": "erickwendel/k8s-job-starwars-example:latest", 16 | "env": [{ 17 | "name": "MONGO_URL", 18 | "value": "mongodb-svc" 19 | }] 20 | }], 21 | 22 | 23 | }, 24 | }, 25 | 26 | "backoffLimit": 4 27 | } 28 | } -------------------------------------------------------------------------------- /module-14 - jobs and cronjobs/2. cron-job/cron-job.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "batch/v1beta1", 3 | "kind": "CronJob", 4 | "metadata": { 5 | "name": "hello" 6 | }, 7 | "spec": { 8 | "schedule": "*/1 * * * *", 9 | "jobTemplate": { 10 | "spec": { 11 | "template": { 12 | "spec": { 13 | "containers": [{ 14 | "name": "job-starwars", 15 | "image": "erickwendel/k8s-job-starwars-example:latest", 16 | "env": [{ 17 | "name": "MONGO_URL", 18 | "value": "mongodb-svc" 19 | }] 20 | }], 21 | "restartPolicy": "OnFailure" 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /module-15 - namespaces/docker-registry-secret.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | ".dockerconfigjson": "eyJhdXRocyI6eyJrOHNjb3Vyc2UuYXp1cmVjci5pbyI6eyJ1c2VybmFtZSI6Ims4c2NvdXJzZSIsInBhc3N3b3JkIjoiWDJzVDFIZnYxVzJBVmhoTkplbXdoUT1wajhzWEEwaWciLCJlbWFpbCI6ImVyaWNrLnNwZWFrZXJAaG90bWFpbC5jb20iLCJhdXRoIjoiYXpoelkyOTFjbk5sT2xneWMxUXhTR1oyTVZjeVFWWm9hRTVLWlcxM2FGRTljR280YzFoQk1HbG4ifX19" 5 | }, 6 | "kind": "Secret", 7 | "metadata": { 8 | "creationTimestamp": "2018-04-29T19:49:57Z", 9 | "name": "acr-credentials", 10 | "namespace": "production", 11 | "resourceVersion": "281659", 12 | "selfLink": "/api/v1/namespaces/production/secrets/acr-credentials", 13 | "uid": "7e87e89f-4be6-11e8-a25b-0a58ac1f1167" 14 | }, 15 | "type": "kubernetes.io/dockerconfigjson" 16 | } 17 | -------------------------------------------------------------------------------- /module-15 - namespaces/heroes-deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "namespace": "production", 6 | "name": "api-heroes", 7 | "labels": { 8 | "version": "v1", 9 | "app": "api-heroes" 10 | } 11 | }, 12 | "spec": { 13 | "replicas": 3, 14 | "selector": { 15 | "matchLabels": { 16 | "version": "v1", 17 | "app": "api-heroes" 18 | } 19 | }, 20 | "template": { 21 | "metadata": { 22 | "labels": { 23 | "version": "v1", 24 | "app": "api-heroes" 25 | } 26 | }, 27 | "spec": { 28 | "containers": [ 29 | { 30 | "name": "api-heroes", 31 | "image": "k8scourse.azurecr.io/api-heroes", 32 | "ports": [ 33 | { 34 | "containerPort": 4000 35 | } 36 | ], 37 | "env": [ 38 | { 39 | "name": "MONGO_URL", 40 | "value": "mongodb-svc" 41 | }, 42 | { 43 | "name": "PORT", 44 | "value": "4000" 45 | } 46 | ] 47 | } 48 | ], 49 | "imagePullSecrets": [ 50 | { 51 | "name": "acr-credentials" 52 | } 53 | ] 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /module-15 - namespaces/heroes-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Service", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "api-heroes-svc", 6 | "labels": { 7 | "version": "v1", 8 | "app": "api-heroes" 9 | } 10 | }, 11 | "spec": { 12 | "selector": { 13 | "app": "api-heroes" 14 | 15 | }, 16 | "type": "LoadBalancer", 17 | "ports": [{ 18 | "protocol": "TCP", 19 | "port": 4000, 20 | "targetPort": 4000 21 | }] 22 | } 23 | } -------------------------------------------------------------------------------- /module-15 - namespaces/namespace.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Namespace", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "development", 6 | "labels": { 7 | "name": "development" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /module-15 - namespaces/namespace.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Namespace", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name": "production", 6 | "labels": { 7 | "name": "production" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /module-15 - namespaces/scripts.sh: -------------------------------------------------------------------------------- 1 | kubectl get namespaces 2 | NAMESPACE=production 3 | kubectl --namespace=$NAMESPACE run nginx --image=nginx 4 | kubectl --namespace=$NAMESPACE get pods 5 | kubectl config set-context $(kubectl config current-context) --namespace $NAMESPACE 6 | kubectl config set-context $(kubectl config current-context) --namespace default 7 | 8 | kubectl get namespaces --show-labels 9 | kubectl config use-context prod 10 | 11 | ACR_NAME=k8scourse 12 | EMAIL=erick.speaker@hotmail.com 13 | PASS=$(az acr credential show -n $ACR_NAME --query "passwords[0].value") 14 | PASS=${PASS//\"} 15 | 16 | ACR_USERNAME=$(az acr credential show -n $ACR_NAME --query "username") 17 | ACR_USERNAME=${ACR_USERNAME//\"} 18 | SECRET_NAME=acr-credentials 19 | 20 | kubectl create secret docker-registry $SECRET_NAME \ 21 | --docker-server=$ACR_NAME.azurecr.io \ 22 | --docker-username=$ACR_NAME \ 23 | --docker-password=$PASS \ 24 | --docker-email=$EMAIL 25 | 26 | kubectl get secret acr-credentials -o yaml -------------------------------------------------------------------------------- /module-16 - resource monitoring and auto-scale/1. working with OMS/oms-agent.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: DaemonSet 3 | metadata: 4 | name: omsagent 5 | spec: 6 | template: 7 | metadata: 8 | labels: 9 | app: omsagent 10 | agentVersion: 1.4.3-174 11 | dockerProviderVersion: 1.0.0-30 12 | spec: 13 | containers: 14 | - name: omsagent 15 | image: "microsoft/oms" 16 | imagePullPolicy: Always 17 | env: 18 | - name: WSID 19 | value: 0fafc2d4-b7ff-4141-a8ce-7f1ba7e1391f 20 | - name: KEY 21 | value: mrpGoggqAHedjDz+Ak62VbK0iSkK6COBICzZuzetNRpY7fQpuT45WAHeKgGPHygXJIpU0tI8sLPcdoZpIeQZBg== 22 | securityContext: 23 | privileged: true 24 | ports: 25 | - containerPort: 25225 26 | protocol: TCP 27 | - containerPort: 25224 28 | protocol: UDP 29 | volumeMounts: 30 | - mountPath: /var/run/docker.sock 31 | name: docker-sock 32 | - mountPath: /var/log 33 | name: host-log 34 | - mountPath: /var/lib/docker/containers 35 | name: containerlog-path 36 | livenessProbe: 37 | exec: 38 | command: 39 | - /bin/bash 40 | - -c 41 | - ps -ef | grep omsagent | grep -v "grep" 42 | initialDelaySeconds: 60 43 | periodSeconds: 60 44 | nodeSelector: 45 | beta.kubernetes.io/os: linux 46 | # Tolerate a NoSchedule taint on master that ACS Engine sets. 47 | tolerations: 48 | - key: "node-role.kubernetes.io/master" 49 | operator: "Equal" 50 | value: "true" 51 | effect: "NoSchedule" 52 | volumes: 53 | - name: docker-sock 54 | hostPath: 55 | path: /var/run/docker.sock 56 | - name: container-hostname 57 | hostPath: 58 | path: /etc/hostname 59 | - name: host-log 60 | hostPath: 61 | path: /var/log 62 | - name: containerlog-path 63 | hostPath: 64 | path: /var/lib/docker/containers 65 | 66 | -------------------------------------------------------------------------------- /module-16 - resource monitoring and auto-scale/2. kubedash/kubedash.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: "extensions/v1beta1" 3 | kind: "Deployment" 4 | metadata: 5 | labels: 6 | name: "kubedash" 7 | name: "kubedash" 8 | namespace: "kube-system" 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | name: "kubedash" 14 | template: 15 | metadata: 16 | labels: 17 | name: "kubedash" 18 | spec: 19 | containers: 20 | - image: "gcr.io/google_containers/kubedash:v0.2.1" 21 | name: "kubedash" 22 | command: 23 | - "/kubedash" 24 | - "--headless=true" 25 | - "--heapster_url=http://localhost:8082" 26 | resources: 27 | limits: 28 | cpu: 50m 29 | memory: 100Mi 30 | volumeMounts: 31 | - name: "ssl-certs" 32 | mountPath: "/etc/ssl/certs" 33 | readOnly: true 34 | - image: gcr.io/google_containers/heapster:v0.18.5 35 | name: "heapster" 36 | resources: 37 | limits: 38 | cpu: 100m 39 | memory: 300Mi 40 | requests: 41 | cpu: 100m 42 | memory: 300Mi 43 | command: 44 | - "/heapster" 45 | - "--source=kubernetes:''" 46 | - "--stats_resolution=30s" 47 | - "--sink_frequency=1m" 48 | volumeMounts: 49 | - name: "ssl-certs" 50 | mountPath: "/etc/ssl/certs" 51 | readOnly: true 52 | volumes: 53 | - name: "ssl-certs" 54 | hostPath: 55 | path: "/etc/ssl/certs" 56 | --- 57 | apiVersion: "v1" 58 | kind: "Service" 59 | metadata: 60 | labels: 61 | name: "kubedash" 62 | name: "kubedash" 63 | namespace: "kube-system" 64 | spec: 65 | type: "LoadBalancer" 66 | ports: 67 | - 68 | port: 80 69 | targetPort: 8289 70 | selector: 71 | name: "kubedash" -------------------------------------------------------------------------------- /module-16 - resource monitoring and auto-scale/3. horizontal pod auto scalling/api-heroes-autoscaling.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Deployment", 4 | "metadata": { 5 | "name": "api-heroes", 6 | "labels": { 7 | "app": "api-heroes" 8 | } 9 | }, 10 | "spec": { 11 | "replicas": 1, 12 | "strategy": { 13 | "type": "RollingUpdate", 14 | "rollingUpdate": { 15 | "maxUnavailable": 0, 16 | "maxSurge": 20 17 | } 18 | }, 19 | "template": { 20 | "metadata": { 21 | "labels": { 22 | "app": "api-heroes" 23 | } 24 | }, 25 | "spec": { 26 | "containers": [ 27 | { 28 | "name": "api-heroes", 29 | "image": "erickwendel/nodejs-with-mongodb-example", 30 | "readinessProbe": { 31 | "httpGet": { 32 | "path": "/heroes", 33 | "port": 4000 34 | }, 35 | "initialDelaySeconds": 15, 36 | "timeoutSeconds": 1 37 | }, 38 | "livenessProbe": { 39 | "httpGet": { 40 | "path": "/heroes", 41 | "port": 4000 42 | }, 43 | "initialDelaySeconds": 15, 44 | "timeoutSeconds": 1 45 | }, 46 | "resources": { 47 | "limits": { 48 | "cpu": "200m", 49 | "memory": "200Mi" 50 | } 51 | }, 52 | "ports": [ 53 | { 54 | "containerPort": 4000 55 | } 56 | ], 57 | "env": [ 58 | { 59 | "name": "MONGO_URL", 60 | "value": "mongodb-svc" 61 | }, 62 | { 63 | "name": "PORT", 64 | "value": "4000" 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /module-16 - resource monitoring and auto-scale/3. horizontal pod auto scalling/script.sh: -------------------------------------------------------------------------------- 1 | kubectl scale deployment api-heroes --replicas 20 2 | kubectl delete hpa api-heroes 3 | kubectl autoscale deployment api-heroes --cpu-percent 10 --max 10 --min 5 4 | kubectl get hpa -w 5 | kubectl describe hpa api-heroes 6 | git clone https://github.com/kubernetes-incubator/metrics-server.git 7 | cd metrics-server/deploy/1.8+ 8 | for D in `ls` 9 | do 10 | echo " creating.. $D" 11 | kubectl create -f $D 12 | done 13 | cd .... 14 | 15 | 16 | HOST=$(kubectl get svc | grep api-heroes | awk '{print $4}') 17 | siege -c60 -t30S http://$HOST:4000/heroes 18 | -------------------------------------------------------------------------------- /module-16 - resource monitoring and auto-scale/4. slack notification/1. watcher-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: kube-slack 5 | namespace: kube-system 6 | spec: 7 | replicas: 1 8 | revisionHistoryLimit: 3 9 | template: 10 | metadata: 11 | annotations: 12 | scheduler.alpha.kubernetes.io/critical-pod: "" 13 | name: kube-slack 14 | labels: 15 | app: kube-slack 16 | spec: 17 | containers: 18 | - name: kube-slack 19 | image: willwill/kube-slack:v3.3.0 20 | env: 21 | - name: SLACK_URL 22 | value: https://hooks.slack.com/services/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 23 | resources: 24 | requests: 25 | memory: 30M 26 | cpu: 5m 27 | tolerations: 28 | - effect: NoSchedule 29 | key: node-role.kubernetes.io/master 30 | - key: CriticalAddonsOnly 31 | operator: Exists -------------------------------------------------------------------------------- /module-16 - resource monitoring and auto-scale/4. slack notification/2. test-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: kube-slack-test 5 | spec: 6 | containers: 7 | - image: willwill/inexisting 8 | name: kube-slack-test --------------------------------------------------------------------------------