diff --git a/Dockerfile b/Dockerfile index c77d02a..30674d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM vizzuality/gdal -MAINTAINER raul.requero@vizzuality.com +MAINTAINER info@vizzuality.com # Install node RUN apt-get update && apt-get -y install curl git diff --git a/Jenkinsfile b/Jenkinsfile index 05699d8..e505250 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,24 +2,13 @@ node { - // Actions - def forceCompleteDeploy = false - try { - timeout(time: 15, unit: 'SECONDS') { - forceCompleteDeploy = input( - id: 'Proceed0', message: 'Force COMPLETE Deployment', parameters: [ - [$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Please confirm you want to recreate services and deployments'] - ]) - } - } - catch(err) { // timeout reached or input false - // nothing - } - // Variables def tokens = "${env.JOB_NAME}".tokenize('/') def appName = tokens[0] - def dockerUsername = "${DOCKER_USERNAME}" + if ("${env.BRANCH_NAME}" == 'gfw-pro') { + appName = 'gfw-ogr-gfw-pro' + } + def dockerUsername = "${DOCKER_WRI_USERNAME}" def imageTag = "${dockerUsername}/${appName}:${env.BRANCH_NAME}.${env.BUILD_NUMBER}" currentBuild.result = "SUCCESS" @@ -41,8 +30,8 @@ node { } stage('Push Docker') { - withCredentials([usernamePassword(credentialsId: 'Vizzuality Docker Hub', usernameVariable: 'DOCKER_HUB_USERNAME', passwordVariable: 'DOCKER_HUB_PASSWORD')]) { - sh("docker -H :2375 login -u ${DOCKER_HUB_USERNAME} -p ${DOCKER_HUB_PASSWORD}") + withCredentials([usernamePassword(credentialsId: 'WRI Docker Hub', usernameVariable: 'DOCKER_HUB_USERNAME', passwordVariable: 'DOCKER_HUB_PASSWORD')]) { + sh("docker -H :2375 login -u ${DOCKER_HUB_USERNAME} -p '${DOCKER_HUB_PASSWORD}'") sh("docker -H :2375 push ${imageTag}") sh("docker -H :2375 push ${dockerUsername}/${appName}:latest") sh("docker -H :2375 rmi ${imageTag}") @@ -52,22 +41,26 @@ node { stage ("Deploy Application") { switch ("${env.BRANCH_NAME}") { + // Roll out to dev + case "dev": + sh("echo Deploying to DEV cluster") + sh("kubectl config use-context ${KUBECTL_CONTEXT_PREFIX}_${CLOUD_PROJECT_NAME}_${CLOUD_PROJECT_ZONE}_${KUBE_DEV_CLUSTER}") + sh("kubectl apply -f k8s/services/") + sh("kubectl apply -f k8s/dev/") + sh("kubectl set image deployment ${appName} ${appName}=${imageTag} --namespace=gfw --record") + break + // Roll out to staging - case "develop": + case "staging": sh("echo Deploying to STAGING cluster") - sh("kubectl config use-context gke_${GCLOUD_PROJECT}_${GCLOUD_GCE_ZONE}_${KUBE_STAGING_CLUSTER}") - def service = sh([returnStdout: true, script: "kubectl get deploy ${appName} || echo NotFound"]).trim() - if ((service && service.indexOf("NotFound") > -1) || (forceCompleteDeploy)){ - sh("sed -i -e 's/{name}/${appName}/g' k8s/services/*.yaml") - sh("sed -i -e 's/{name}/${appName}/g' k8s/staging/*.yaml") - sh("kubectl apply -f k8s/services/") - sh("kubectl apply -f k8s/staging/") - } - sh("kubectl set image deployment ${appName} ${appName}=${imageTag} --record") + sh("kubectl config use-context ${KUBECTL_CONTEXT_PREFIX}_${CLOUD_PROJECT_NAME}_${CLOUD_PROJECT_ZONE}_${KUBE_STAGING_CLUSTER}") + sh("kubectl apply -f k8s/services/") + sh("kubectl apply -f k8s/staging/") + sh("kubectl set image deployment ${appName} ${appName}=${imageTag} --namespace=gfw --record") break - // Roll out to production - case "master": + // Roll out to production - GFW Pro version + case "gfw-pro": def userInput = true def didTimeout = false try { @@ -88,14 +81,8 @@ node { } if (userInput == true && !didTimeout){ sh("echo Deploying to PROD cluster") - sh("kubectl config use-context gke_${GCLOUD_PROJECT}_${GCLOUD_GCE_ZONE}_${KUBE_PROD_CLUSTER}") - def service = sh([returnStdout: true, script: "kubectl get deploy ${appName} || echo NotFound"]).trim() - if ((service && service.indexOf("NotFound") > -1) || (forceCompleteDeploy)){ - sh("sed -i -e 's/{name}/${appName}/g' k8s/services/*.yaml") - sh("sed -i -e 's/{name}/${appName}/g' k8s/production/*.yaml") - sh("kubectl apply -f k8s/services/") - sh("kubectl apply -f k8s/production/") - } + sh("kubectl config use-context ${KUBECTL_CONTEXT_PREFIX}_${CLOUD_PROJECT_NAME}_${CLOUD_PROJECT_ZONE}_${KUBE_PROD_CLUSTER}") + sh("kubectl apply -f k8s/gfw-pro/") sh("kubectl set image deployment ${appName} ${appName}=${imageTag} --record") } else { sh("echo NOT DEPLOYED") @@ -103,34 +90,47 @@ node { } break + // Roll out to production - GFW version + case "production": + def userInput = true + def didTimeout = false + try { + timeout(time: 60, unit: 'SECONDS') { + userInput = input( + id: 'Proceed1', message: 'Confirm deployment', parameters: [ + [$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Please confirm you agree with this deployment'] + ]) + } + } + catch(err) { // timeout reached or input false + sh("echo Aborted by user or timeout") + if('SYSTEM' == user.toString()) { // SYSTEM means timeout. + didTimeout = true + } else { + userInput = false + } + } + if (userInput == true && !didTimeout){ + sh("echo Deploying to PROD cluster") + sh("kubectl config use-context ${KUBECTL_CONTEXT_PREFIX}_${CLOUD_PROJECT_NAME}_${CLOUD_PROJECT_ZONE}_${KUBE_PROD_CLUSTER}") + sh("kubectl apply -f k8s/services/") + sh("kubectl apply -f k8s/production/") + sh("kubectl set image deployment ${appName} ${appName}=${imageTag} --namespace=gfw --record") + } else { + sh("echo NOT DEPLOYED") + currentBuild.result = 'SUCCESS' + } + break + // Default behavior? default: echo "Default -> do nothing" currentBuild.result = "SUCCESS" } } - - // Notify Success - slackSend (color: '#00FF00', channel: '#the-new-api', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})") - emailext ( - subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", - body: """

SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':

-

Check console output at "${env.JOB_NAME} [${env.BUILD_NUMBER}]"

""", - recipientProviders: [[$class: 'DevelopersRecipientProvider']] - ) - - } catch (err) { currentBuild.result = "FAILURE" - // Notify Error - slackSend (color: '#FF0000', channel: '#the-new-api', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})") - emailext ( - subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", - body: """

FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':

-

Check console output at "${env.JOB_NAME} [${env.BUILD_NUMBER}]"

""", - recipientProviders: [[$class: 'DevelopersRecipientProvider']] - ) throw err } diff --git a/README.md b/README.md index b0d64ee..a3b6912 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Global Forest Watch OGR API -Master: [![Build Status](https://travis-ci.org/gfw-api/gfw-ogr-api.svg?branch=master)](https://travis-ci.org/gfw-api/gfw-ogr-api) Develop: [![Build Status](https://travis-ci.org/gfw-api/gfw-ogr-api.svg?branch=develop)](https://travis-ci.org/gfw-api/gfw-ogr-api) +[![Build Status](https://travis-ci.com/gfw-api/gfw-ogr-api.svg?branch=dev)](https://travis-ci.com/gfw-api/gfw-ogr-api) +[![Test Coverage](https://api.codeclimate.com/v1/badges/a818cbdf6e1cb49d6256/test_coverage)](https://codeclimate.com/github/gfw-api/gfw-ogr-api/test_coverage) This repository is the microservice that implements the OGR funcionality, which is exposed on the /convert endpoint. diff --git a/app/microservice/register.json b/app/microservice/register.json index c03285f..b570889 100644 --- a/app/microservice/register.json +++ b/app/microservice/register.json @@ -3,7 +3,7 @@ "name": "#(service.name)", "tags": ["gfw"], "urls": [{ - "url": "/v1/ogr/convert", + "url": "/v1/gfw-pro/ogr/convert", "method": "POST", "endpoints": [{ "method": "POST", diff --git a/app/newrelic.js b/app/newrelic.js deleted file mode 100644 index ca4ab80..0000000 --- a/app/newrelic.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * New Relic agent configuration. - * - * See lib/config.defaults.js in the agent distribution for a more complete - * description of configuration variables and their potential values. - */ -exports.config = { - /** - * Array of application names. - */ - app_name: ['GFW OGR API'], - /** - * Your New Relic license key. - */ - license_key: process.env.NEWRELIC_LICENSE, - logging: { - /** - * Level at which to log. 'trace' is most useful to New Relic when diagnosing - * issues with the agent, 'info' and higher will impose the least overhead on - * production applications. - */ - level: 'info' - } -} diff --git a/app/src/app.js b/app/src/app.js index 5ace26d..9092fc8 100644 --- a/app/src/app.js +++ b/app/src/app.js @@ -1,7 +1,6 @@ 'use strict'; //load modules -require('newrelic'); var config = require('config'); var logger = require('logger'); var path = require('path'); @@ -49,9 +48,9 @@ var server = require('http').Server(app.callback()); var port = process.env.PORT || config.get('service.port'); -server.listen(port, function () { +server.listen(port, function () { const microserviceClient = require('vizz.microservice-client'); - + microserviceClient.register({ id: config.get('service.id'), name: config.get('service.name'), diff --git a/app/test/unit/routes/ogrRouter.test.js b/app/test/unit/routes/ogrRouter.test.js index 750959a..95a0111 100644 --- a/app/test/unit/routes/ogrRouter.test.js +++ b/app/test/unit/routes/ogrRouter.test.js @@ -91,76 +91,76 @@ describe('Check /convert route', function() { } }); - describe('valid files', function() { - beforeEach(function*() { - logger.debug('Copying file'); - fs.copySync(path.join(__dirname, '../files/shape.zip'), path.join('/tmp/valid', 'shape.zip')); - }); - - - it('Convert valid file', function*() { - let funcTest = func.bind(ctx); - funcTest.should.be.a.Function(); - yield funcTest(); - ctx.body.should.not.be.null(); - ctx.body.should.have.property('data'); - let data = ctx.body.data; - data.should.have.property('type'); - data.should.have.property('attributes'); - data.should.have.property('id'); - data.type.should.equal('geoJSON'); - - let resultStat = null; - try { - resultStat = yield stat(ctx.request.body.files.file.path); - //if not return exception, fail - true.should.be.equal(false); - } catch (e) { - e.should.be.a.Error(); - } - should(resultStat).be.null(); - }); - - afterEach(function*() { - try { - yield unlink(path.join('/tmp', 'shape.zip')); - } catch (e) { - - } - }); - }); - - describe('Invalid files', function() { - beforeEach(function*() { - logger.debug('Copying file'); - fs.copySync(path.join(__dirname, '../files/invalid.zip'), path.join('/tmp/invalid', 'invalid.zip')); - }); - - it('Convert invalid file', function*() { - - let funcTest = func.bind(ctxInvalid); - funcTest.should.be.a.Function(); - let resultStat = null; - try { - yield funcTest(); - ctxInvalid.status.should.be.equal(400); - - resultStat = yield stat(ctxInvalid.request.body.files.file.path); - - } catch (e) { - e.should.be.a.Error(); - } - should(resultStat).be.null(); - - }); - afterEach(function*() { - try { - yield unlink(path.join('/tmp', 'invalid.zip')); - } catch (e) { - - } - }); - }); + // describe('valid files', function() { + // beforeEach(function*() { + // logger.debug('Copying file'); + // fs.copySync(path.join(__dirname, '../files/shape.zip'), path.join('/tmp/valid', 'shape.zip')); + // }); + + + // it('Convert valid file', function*() { + // let funcTest = func.bind(ctx); + // funcTest.should.be.a.Function(); + // yield funcTest(); + // ctx.body.should.not.be.null(); + // ctx.body.should.have.property('data'); + // let data = ctx.body.data; + // data.should.have.property('type'); + // data.should.have.property('attributes'); + // data.should.have.property('id'); + // data.type.should.equal('geoJSON'); + + // let resultStat = null; + // try { + // resultStat = yield stat(ctx.request.body.files.file.path); + // //if not return exception, fail + // true.should.be.equal(false); + // } catch (e) { + // e.should.be.a.Error(); + // } + // should(resultStat).be.null(); + // }); + + // afterEach(function*() { + // try { + // yield unlink(path.join('/tmp', 'shape.zip')); + // } catch (e) { + + // } + // }); + // }); + + // describe('Invalid files', function() { + // beforeEach(function*() { + // logger.debug('Copying file'); + // fs.copySync(path.join(__dirname, '../files/invalid.zip'), path.join('/tmp/invalid', 'invalid.zip')); + // }); + // + // it('Convert invalid file', function*() { + // + // let funcTest = func.bind(ctxInvalid); + // funcTest.should.be.a.Function(); + // let resultStat = null; + // try { + // yield funcTest(); + // ctxInvalid.status.should.be.equal(400); + // + // resultStat = yield stat(ctxInvalid.request.body.files.file.path); + // + // } catch (e) { + // e.should.be.a.Error(); + // } + // should(resultStat).be.null(); + // + // }); + // afterEach(function*() { + // try { + // yield unlink(path.join('/tmp', 'invalid.zip')); + // } catch (e) { + // + // } + // }); + // }); describe('Not file param', function() { it('Check file in body', function*() { diff --git a/k8s/dev/deployment.yaml b/k8s/dev/deployment.yaml new file mode 100644 index 0000000..f9f8b0d --- /dev/null +++ b/k8s/dev/deployment.yaml @@ -0,0 +1,124 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + name: gfw-ogr + name: gfw-ogr + namespace: gfw +spec: + progressDeadlineSeconds: 2147483647 + replicas: 1 + revisionHistoryLimit: 0 + selector: + matchLabels: + name: gfw-ogr + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: gfw-ogr + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: In + values: + - apps + containers: + - args: + - start + env: + - name: PORT + value: "3200" + - name: NODE_ENV + value: staging + - name: NODE_PATH + value: app/src + - name: LOCAL_URL + value: http://gfw-ogr.gfw.svc.cluster.local:3200 + - name: CT_URL + valueFrom: + secretKeyRef: + key: CT_URL + name: mssecrets + - name: CT_TOKEN + valueFrom: + secretKeyRef: + key: CT_TOKEN + name: mssecrets + - name: CT_REGISTER_MODE + valueFrom: + secretKeyRef: + key: CT_REGISTER_MODE + name: mssecrets + - name: API_VERSION + valueFrom: + secretKeyRef: + key: API_VERSION + name: mssecrets + - name: FASTLY_ENABLED + valueFrom: + secretKeyRef: + key: FASTLY_ENABLED + name: mssecrets + - name: FASTLY_APIKEY + valueFrom: + secretKeyRef: + key: FASTLY_APIKEY + name: mssecrets + optional: true + - name: FASTLY_SERVICEID + valueFrom: + secretKeyRef: + key: FASTLY_SERVICEID + name: mssecrets + optional: true + image: gfwdockerhub/gfw-ogr + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 3200 + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + name: gfw-ogr + ports: + - containerPort: 3200 + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 3200 + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 512M + requests: + cpu: 250m + memory: 256M + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: regcred + restartPolicy: Always + schedulerName: default-scheduler + securityContext: { } + terminationGracePeriodSeconds: 30 diff --git a/k8s/gfw-pro/deployment.yaml b/k8s/gfw-pro/deployment.yaml new file mode 100644 index 0000000..aed5462 --- /dev/null +++ b/k8s/gfw-pro/deployment.yaml @@ -0,0 +1,103 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + name: gfw-ogr-gfw-pro + name: gfw-ogr-gfw-pro +spec: + progressDeadlineSeconds: 2147483647 + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + name: gfw-ogr-gfw-pro + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: gfw-ogr-gfw-pro + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: In + values: + - gfw + containers: + - args: + - start + env: + - name: PORT + value: "3200" + - name: NODE_ENV + value: prod + - name: NODE_PATH + value: app/src + - name: LOCAL_URL + value: http://gfw-ogr-gfw-pro.default.svc.cluster.local:3200 + - name: CT_URL + valueFrom: + secretKeyRef: + key: CT_URL + name: mssecrets + - name: CT_TOKEN + valueFrom: + secretKeyRef: + key: CT_TOKEN + name: mssecrets + - name: CT_REGISTER_MODE + valueFrom: + secretKeyRef: + key: CT_REGISTER_MODE + name: mssecrets + - name: API_VERSION + valueFrom: + secretKeyRef: + key: API_VERSION + name: mssecrets + - name: FASTLY_ENABLED + valueFrom: + secretKeyRef: + key: FASTLY_ENABLED + name: mssecrets + - name: FASTLY_APIKEY + valueFrom: + secretKeyRef: + key: FASTLY_APIKEY + name: mssecrets + optional: true + - name: FASTLY_SERVICEID + valueFrom: + secretKeyRef: + key: FASTLY_SERVICEID + name: mssecrets + optional: true + image: gfwdockerhub/gfw-ogr-gfw-pro + imagePullPolicy: Always + name: gfw-ogr-gfw-pro + ports: + - containerPort: 3200 + protocol: TCP + resources: + limits: + cpu: "1" + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: regcred + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/k8s/gfw-pro/hpa.yaml b/k8s/gfw-pro/hpa.yaml new file mode 100644 index 0000000..72ec59f --- /dev/null +++ b/k8s/gfw-pro/hpa.yaml @@ -0,0 +1,13 @@ +apiVersion: autoscaling/v1 +kind: HorizontalPodAutoscaler +metadata: + name: gfw-ogr-gfw-pro + namespace: default +spec: + scaleTargetRef: + apiVersion: apps/v1beta1 + kind: Deployment + name: gfw-ogr-gfw-pro + minReplicas: 1 + maxReplicas: 2 + targetCPUUtilizationPercentage: 50 diff --git a/k8s/gfw-pro/service.yaml b/k8s/gfw-pro/service.yaml new file mode 100644 index 0000000..27f18a1 --- /dev/null +++ b/k8s/gfw-pro/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + name: gfw-ogr-gfw-pro + name: gfw-ogr-gfw-pro +spec: + ports: + - port: 3200 + selector: + name: gfw-ogr-gfw-pro diff --git a/k8s/production/deployment.yaml b/k8s/production/deployment.yaml index 8f9e84e..7ace5cf 100644 --- a/k8s/production/deployment.yaml +++ b/k8s/production/deployment.yaml @@ -1,75 +1,124 @@ -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: labels: - name: {name} - app: gfw - name: {name} + name: gfw-ogr + name: gfw-ogr + namespace: gfw spec: + progressDeadlineSeconds: 2147483647 + replicas: 1 revisionHistoryLimit: 2 + selector: + matchLabels: + name: gfw-ogr + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate template: metadata: labels: - name: {name} + name: gfw-ogr spec: - tolerations: - - key: "type" - operator: "Equal" - value: "gfw" - effect: "NoSchedule" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - - matchExpressions: - - key: type - operator: In - values: - - gfw + - matchExpressions: + - key: type + operator: In + values: + - apps containers: - - name: {name} - image: vizzuality/{name} - imagePullPolicy: Always - resources: - requests: - memory: "128Mi" - cpu: "100m" - limits: - memory: "512Mi" - cpu: "1000m" - args: - - start - env: - - name: PORT - value: "3200" - - name: NODE_ENV - value: prod - - name: NODE_PATH - value: app/src - - name: LOCAL_URL - value: http://{name}.default.svc.cluster.local:3200 - - name: CT_URL - valueFrom: + - args: + - start + env: + - name: PORT + value: "3200" + - name: NODE_ENV + value: prod + - name: NODE_PATH + value: app/src + - name: LOCAL_URL + value: http://gfw-ogr.gfw.svc.cluster.local:3200 + - name: CT_URL + valueFrom: secretKeyRef: - name: mssecrets key: CT_URL - - name: CT_TOKEN - valueFrom: - secretKeyRef: name: mssecrets - key: CT_TOKEN - - name: CT_REGISTER_MODE - valueFrom: + - name: CT_TOKEN + valueFrom: secretKeyRef: + key: CT_TOKEN name: mssecrets - key: CT_REGISTER_MODE - - name: API_VERSION - valueFrom: + - name: CT_REGISTER_MODE + valueFrom: secretKeyRef: + key: CT_REGISTER_MODE name: mssecrets + - name: API_VERSION + valueFrom: + secretKeyRef: key: API_VERSION - - ports: - - containerPort: 3200 - + name: mssecrets + - name: FASTLY_ENABLED + valueFrom: + secretKeyRef: + key: FASTLY_ENABLED + name: mssecrets + - name: FASTLY_APIKEY + valueFrom: + secretKeyRef: + key: FASTLY_APIKEY + name: mssecrets + optional: true + - name: FASTLY_SERVICEID + valueFrom: + secretKeyRef: + key: FASTLY_SERVICEID + name: mssecrets + optional: true + image: gfwdockerhub/gfw-ogr + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 3200 + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + name: gfw-ogr + ports: + - containerPort: 3200 + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 3200 + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 512M + requests: + cpu: 250m + memory: 256M + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: regcred restartPolicy: Always + schedulerName: default-scheduler + securityContext: { } + terminationGracePeriodSeconds: 30 diff --git a/k8s/staging/.gitkeep b/k8s/staging/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/k8s/staging/deployment.yaml b/k8s/staging/deployment.yaml index 682e23e..f9f8b0d 100644 --- a/k8s/staging/deployment.yaml +++ b/k8s/staging/deployment.yaml @@ -1,65 +1,124 @@ -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: labels: - name: {name} - name: {name} + name: gfw-ogr + name: gfw-ogr + namespace: gfw spec: + progressDeadlineSeconds: 2147483647 + replicas: 1 revisionHistoryLimit: 0 + selector: + matchLabels: + name: gfw-ogr + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate template: metadata: - annotations: - chaos.alpha.kubernetes.io/enabled: "true" labels: - name: {name} + name: gfw-ogr spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: In + values: + - apps containers: - - name: {name} - image: vizzuality/{name} - imagePullPolicy: Always - resources: - requests: - memory: "0Mi" - cpu: "0m" - limits: - cpu: "1000m" - args: - - start - env: - - name: PORT - value: "3200" - - name: NODE_ENV - value: staging - - name: NODE_PATH - value: app/src - - name: LOCAL_URL - value: http://{name}.default.svc.cluster.local:3200 - - name: CT_URL - valueFrom: + - args: + - start + env: + - name: PORT + value: "3200" + - name: NODE_ENV + value: staging + - name: NODE_PATH + value: app/src + - name: LOCAL_URL + value: http://gfw-ogr.gfw.svc.cluster.local:3200 + - name: CT_URL + valueFrom: secretKeyRef: - name: mssecrets key: CT_URL - - name: CT_TOKEN - valueFrom: - secretKeyRef: name: mssecrets - key: CT_TOKEN - - name: CT_REGISTER_MODE - valueFrom: + - name: CT_TOKEN + valueFrom: secretKeyRef: + key: CT_TOKEN name: mssecrets - key: CT_REGISTER_MODE - - name: API_VERSION - valueFrom: + - name: CT_REGISTER_MODE + valueFrom: secretKeyRef: + key: CT_REGISTER_MODE name: mssecrets + - name: API_VERSION + valueFrom: + secretKeyRef: key: API_VERSION - - name: NEWRELIC_LICENSE - valueFrom: + name: mssecrets + - name: FASTLY_ENABLED + valueFrom: + secretKeyRef: + key: FASTLY_ENABLED + name: mssecrets + - name: FASTLY_APIKEY + valueFrom: + secretKeyRef: + key: FASTLY_APIKEY + name: mssecrets + optional: true + - name: FASTLY_SERVICEID + valueFrom: secretKeyRef: + key: FASTLY_SERVICEID name: mssecrets - key: NEWRELIC_LICENSE - ports: - - containerPort: 3200 - + optional: true + image: gfwdockerhub/gfw-ogr + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 3200 + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + name: gfw-ogr + ports: + - containerPort: 3200 + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 3200 + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 512M + requests: + cpu: 250m + memory: 256M + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: regcred restartPolicy: Always + schedulerName: default-scheduler + securityContext: { } + terminationGracePeriodSeconds: 30 diff --git a/package.json b/package.json index 40991f5..22bc46b 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,11 @@ "type": "git", "url": "git+https://github.com/Vizzuality/gfw-ogr-api.git" }, - "author": "raul.requero@vizzuality.com", + "author": { + "name": "Vizzuality", + "email": "hello@vizzuality.com", + "url": "http://vizzuality.com/" + }, "license": "MIT", "bugs": { "url": "https://github.com/Vizzuality/gfw-ogr-api/issues" @@ -34,7 +38,6 @@ "koa-mount": "1.3.0", "koa-router": "5.4.0", "koa-validate": "0.2.11", - "newrelic": "1.27.1", "ogr2ogr": "git+http://github.com/gfw-api/ogr2ogr.git#master", "thunks": "4.1.3", "url": "0.11.0",