mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-04-07 03:26:54 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e6d61e77e | ||
|
|
c7c7d699c9 | ||
|
|
067751c67d | ||
|
|
73b658d711 | ||
|
|
e5516b38cb | ||
|
|
39130004d5 | ||
|
|
d4b615e3a2 | ||
|
|
98e133a7be | ||
|
|
7674b76dab | ||
|
|
8fa39d90be | ||
|
|
638bdc8e83 | ||
|
|
b565a67dec | ||
|
|
65d077291b | ||
|
|
e9d11c247e | ||
|
|
126ac55801 | ||
|
|
306aac3e65 | ||
|
|
55318b0c20 | ||
|
|
1865faf7ce | ||
|
|
9edd7abbe8 | ||
|
|
1c4acc0b33 | ||
|
|
6274f16b9b | ||
|
|
93e338a964 | ||
|
|
73b03b77fc | ||
|
|
0135757fbd | ||
|
|
ea1fe87d49 |
@@ -33,6 +33,7 @@ jobs:
|
|||||||
echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin;
|
echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin;
|
||||||
echo $QUAY_PASS | docker login -u $QUAY_USER --password-stdin quay.io;
|
echo $QUAY_PASS | docker login -u $QUAY_USER --password-stdin quay.io;
|
||||||
make push-container;
|
make push-container;
|
||||||
|
make push-base;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
push-binary:
|
push-binary:
|
||||||
|
|||||||
10
Dockerfile.base
Normal file
10
Dockerfile.base
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
FROM golang:1.14
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
|
|
||||||
|
# copy modules manifests
|
||||||
|
COPY go.mod go.mod
|
||||||
|
COPY go.sum go.sum
|
||||||
|
|
||||||
|
# cache modules
|
||||||
|
RUN go mod download
|
||||||
10
Makefile
10
Makefile
@@ -33,6 +33,12 @@ build-charts:
|
|||||||
build-container:
|
build-container:
|
||||||
docker build -t $(DOCKER_IMAGE_NAME):$(VERSION) .
|
docker build -t $(DOCKER_IMAGE_NAME):$(VERSION) .
|
||||||
|
|
||||||
|
build-base:
|
||||||
|
docker build -f Dockerfile.base -t $(DOCKER_REPOSITORY)/podinfo-base:latest .
|
||||||
|
|
||||||
|
push-base: build-base
|
||||||
|
docker push $(DOCKER_REPOSITORY)/podinfo-base:latest
|
||||||
|
|
||||||
test-container:
|
test-container:
|
||||||
@docker rm -f podinfo || true
|
@docker rm -f podinfo || true
|
||||||
@docker run -dp 9898:9898 --name=podinfo $(DOCKER_IMAGE_NAME):$(VERSION)
|
@docker run -dp 9898:9898 --name=podinfo $(DOCKER_IMAGE_NAME):$(VERSION)
|
||||||
@@ -57,6 +63,10 @@ version-set:
|
|||||||
sed -i '' "s/appVersion: $$current/appVersion: $$next/g" charts/podinfo/Chart.yaml && \
|
sed -i '' "s/appVersion: $$current/appVersion: $$next/g" charts/podinfo/Chart.yaml && \
|
||||||
sed -i '' "s/version: $$current/version: $$next/g" charts/podinfo/Chart.yaml && \
|
sed -i '' "s/version: $$current/version: $$next/g" charts/podinfo/Chart.yaml && \
|
||||||
sed -i '' "s/podinfo:$$current/podinfo:$$next/g" kustomize/deployment.yaml && \
|
sed -i '' "s/podinfo:$$current/podinfo:$$next/g" kustomize/deployment.yaml && \
|
||||||
|
sed -i '' "s/podinfo:$$current/podinfo:$$next/g" deploy/webapp/frontend/deployment.yaml && \
|
||||||
|
sed -i '' "s/podinfo:$$current/podinfo:$$next/g" deploy/webapp/backend/deployment.yaml && \
|
||||||
|
sed -i '' "s/podinfo:$$current/podinfo:$$next/g" deploy/bases/frontend/deployment.yaml && \
|
||||||
|
sed -i '' "s/podinfo:$$current/podinfo:$$next/g" deploy/bases/backend/deployment.yaml && \
|
||||||
echo "Version $$next set in code, deployment, chart and kustomize"
|
echo "Version $$next set in code, deployment, chart and kustomize"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ Web API:
|
|||||||
* `POST /token` issues a JWT token valid for one minute `JWT=$(curl -sd 'anon' podinfo:9898/token | jq -r .token)`
|
* `POST /token` issues a JWT token valid for one minute `JWT=$(curl -sd 'anon' podinfo:9898/token | jq -r .token)`
|
||||||
* `GET /token/validate` validates the JWT token `curl -H "Authorization: Bearer $JWT" podinfo:9898/token/validate`
|
* `GET /token/validate` validates the JWT token `curl -H "Authorization: Bearer $JWT" podinfo:9898/token/validate`
|
||||||
* `GET /configs` returns a JSON with configmaps and/or secrets mounted in the `config` volume
|
* `GET /configs` returns a JSON with configmaps and/or secrets mounted in the `config` volume
|
||||||
|
* `POST /cache` saves the posted content to Redis and returns the SHA1 hash of the content
|
||||||
|
* `GET /store/{hash}` returns the content from Redis if the key exists
|
||||||
* `POST /store` writes the posted content to disk at /data/hash and returns the SHA1 hash of the content
|
* `POST /store` writes the posted content to disk at /data/hash and returns the SHA1 hash of the content
|
||||||
* `GET /store/{hash}` returns the content of the file /data/hash if exists
|
* `GET /store/{hash}` returns the content of the file /data/hash if exists
|
||||||
* `GET /ws/echo` echos content via websockets `podcli ws ws://localhost:9898/ws/echo`
|
* `GET /ws/echo` echos content via websockets `podcli ws ws://localhost:9898/ws/echo`
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
version: 3.2.2
|
version: 3.3.0
|
||||||
appVersion: 3.2.2
|
appVersion: 3.3.0
|
||||||
name: podinfo
|
name: podinfo
|
||||||
engine: gotpl
|
engine: gotpl
|
||||||
description: Podinfo Helm chart for Kubernetes
|
description: Podinfo Helm chart for Kubernetes
|
||||||
|
|||||||
@@ -29,48 +29,56 @@ The command removes all the Kubernetes components associated with the chart and
|
|||||||
|
|
||||||
The following tables lists the configurable parameters of the podinfo chart and their default values.
|
The following tables lists the configurable parameters of the podinfo chart and their default values.
|
||||||
|
|
||||||
Parameter | Description | Default
|
Parameter | Default | Description
|
||||||
--- | --- | ---
|
--- | --- | ---
|
||||||
`affinity` | node/pod affinities | None
|
`replicaCount` | `1` | Desired number of pods
|
||||||
`backend` | echo backend URL | None
|
`logLevel` | `info` | Log level: `debug`, `info`, `warn`, `error`, `flat` or `panic`
|
||||||
`backends` | echo backend URL array | None
|
`backend` | `None` | Echo backend URL
|
||||||
`faults.delay` | random HTTP response delays between 0 and 5 seconds | `false`
|
`backends` | `[]` | Array of echo backend URLs
|
||||||
`faults.error` | 1/3 chances of a random HTTP response error | `false`
|
`cache` | `None` | Redis address in the format `<host>:<port>`
|
||||||
`faults.unhealthy` | when set, the healthy state is never reached | `false`
|
`ui.color` | `#34577c` | UI color
|
||||||
`faults.unready` | when set, the ready state is never reached | `false`
|
`ui.message` | `None` | UI greetings message
|
||||||
`hpa.enabled` | enables HPA | `false`
|
`ui.logo` | `None` | UI logo
|
||||||
`hpa.cpu` | target CPU usage per pod | None
|
`faults.delay` | `false` | Random HTTP response delays between 0 and 5 seconds
|
||||||
`hpa.memory` | target memory usage per pod | None
|
`faults.error` | `false` | 1/3 chances of a random HTTP response error
|
||||||
`hpa.requests` | target requests per second per pod | None
|
`faults.unhealthy` | `false` | When set, the healthy state is never reached
|
||||||
`hpa.maxReplicas` | maximum pod replicas | `10`
|
`faults.unready` | `false` | When set, the ready state is never reached
|
||||||
`image.pullPolicy` | image pull policy | `IfNotPresent`
|
`faults.testFail` | `false` | When set, a helm test is included which always fails
|
||||||
`image.repository` | image repository | `stefanprodan/podinfo`
|
`faults.testTimeout` | `false` | When set, a helm test is included which always times out
|
||||||
`image.tag` | image tag | `<VERSION>`
|
`h2c.enabled` | `false` | Allow upgrading to h2c
|
||||||
`ingress.enabled` | enables ingress | `false`
|
`image.repository` | `stefanprodan/podinfo` | Image repository
|
||||||
`ingress.annotations` | ingress annotations | None
|
`image.tag` | `<VERSION>` | Image tag
|
||||||
`ingress.hosts` | ingress accepted hostnames | None
|
`image.pullPolicy` | `IfNotPresent` | Image pull policy
|
||||||
`ingress.tls` | ingress TLS configuration | None
|
`service.enabled` | `true` | Create a Kubernetes Service, should be disabled when using [Flagger](https://flagger.app)
|
||||||
`message` | UI greetings message | None
|
`service.type` | `ClusterIP` | Type of the Kubernetes Service
|
||||||
`nodeSelector` | node labels for pod assignment | `{}`
|
`service.metricsPort` | `9797` | Prometheus metrics endpoint port
|
||||||
`replicaCount` | desired number of pods | `2`
|
`service.httpPort` | `9898` | Container HTTP port
|
||||||
`resources.requests/cpu` | pod CPU request | `1m`
|
`service.externalPort` | `9898` | ClusterIP HTTP port
|
||||||
`resources.requests/memory` | pod memory request | `16Mi`
|
`service.grpcPort` | `9999` | ClusterIP gPRC port
|
||||||
`resources.limits/cpu` | pod CPU limit | None
|
`service.grpcService` | `podinfo` | gPRC service name
|
||||||
`resources.limits/memory` | pod memory limit | None
|
`service.nodePort` | `31198` | NodePort for the HTTP endpoint
|
||||||
`service.enabled` | create Kubernetes service (should be disabled when using Flagger) | `true`
|
`hpa.enabled` | `false` | Enables the Kubernetes HPA
|
||||||
`service.metricsPort` | Prometheus metrics endpoint port | `9797`
|
`hpa.maxReplicas` | `10` | Maximum amount of pods
|
||||||
`service.externalPort` | ClusterIP HTTP port | `9898`
|
`hpa.cpu` | `None` | Target CPU usage per pod
|
||||||
`service.httpPort` | container HTTP port | `9898`
|
`hpa.memory` | `None` | Target memory usage per pod
|
||||||
`service.nodePort` | NodePort for the HTTP endpoint | `31198`
|
`hpa.requests` | `None` | Target HTTP requests per second per pod
|
||||||
`service.grpcPort` | ClusterIP gPRC port | `9999`
|
`serviceAccount.enabled` | `false` | Whether a service account should be created
|
||||||
`service.grpcService` | gPRC service name | `podinfo`
|
`serviceAccount.name` | `None` | The name of the service account to use, if not set and create is true, a name is generated using the fullname template
|
||||||
`service.type` | type of service | `ClusterIP`
|
`linkerd.profile.enabled` | `false` | Create Linkerd service profile
|
||||||
`tolerations` | list of node taints to tolerate | `[]`
|
`serviceMonitor.enabled` | `false` | Whether a Prometheus Operator service monitor should be created
|
||||||
`serviceAccount.enabled` | specifies whether a service account should be created | `false`
|
`serviceMonitor.interval` | `15s` | Prometheus scraping interval
|
||||||
`serviceAccount.name` | the name of the service account to use, if not set and create is true, a name is generated using the fullname template | None
|
`ingress.enabled` | `false` | Enables Ingress
|
||||||
`linkerd.profile.enabled` | create Linkerd service profile | `false`
|
`ingress.annotations` | `{}` | Ingress annotations
|
||||||
`serviceMonitor.enabled` | specifies whether a Prometheus Operator service monitor should be created | `false`
|
`ingress.path` | `/*` | Ingress path
|
||||||
`serviceMonitor.interval` | Prometheus scraping interval | `15s`
|
`ingress.hosts` | `[]` | Ingress accepted hosts
|
||||||
|
`ingress.tls` | `[]` | Ingress TLS configuration
|
||||||
|
`resources.requests.cpu` | `1m` | Pod CPU request
|
||||||
|
`resources.requests.memory` | `16Mi` | Pod memory request
|
||||||
|
`resources.limits.cpu` | `None` | Pod CPU limit
|
||||||
|
`resources.limits.memory` | `None` | Pod memory limit
|
||||||
|
`nodeSelector` | `{}` | Node labels for pod assignment
|
||||||
|
`tolerations` | `[]` | List of node taints to tolerate
|
||||||
|
`affinity` | `None` | Node/pod affinities
|
||||||
|
|
||||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||||
|
|
||||||
@@ -86,5 +94,3 @@ $ helm install stable/podinfo --name my-release -f values.yaml
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **Tip**: You can use the default [values.yaml](values.yaml)
|
> **Tip**: You can use the default [values.yaml](values.yaml)
|
||||||
```
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ spec:
|
|||||||
{{- range .Values.backends }}
|
{{- range .Values.backends }}
|
||||||
- --backend-url={{ . }}
|
- --backend-url={{ . }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.cache }}
|
||||||
|
- --cache-server={{ .Values.cache }}
|
||||||
|
{{- end }}
|
||||||
- --level={{ .Values.logLevel }}
|
- --level={{ .Values.logLevel }}
|
||||||
- --random-delay={{ .Values.faults.delay }}
|
- --random-delay={{ .Values.faults.delay }}
|
||||||
- --random-error={{ .Values.faults.error }}
|
- --random-error={{ .Values.faults.error }}
|
||||||
@@ -64,7 +67,7 @@ spec:
|
|||||||
env:
|
env:
|
||||||
{{- if .Values.ui.message }}
|
{{- if .Values.ui.message }}
|
||||||
- name: PODINFO_UI_MESSAGE
|
- name: PODINFO_UI_MESSAGE
|
||||||
value: {{ .Values.ui.message }}
|
value: {{ quote .Values.ui.message }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .Values.ui.logo }}
|
{{- if .Values.ui.logo }}
|
||||||
- name: PODINFO_UI_LOGO
|
- name: PODINFO_UI_LOGO
|
||||||
|
|||||||
26
charts/podinfo/templates/tests/fail.yaml
Normal file
26
charts/podinfo/templates/tests/fail.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{{- if .Values.faults.test }}
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: {{ template "podinfo.fullname" . }}-fault-test-{{ randAlphaNum 5 | lower }}
|
||||||
|
labels:
|
||||||
|
heritage: {{ .Release.Service }}
|
||||||
|
release: {{ .Release.Name }}
|
||||||
|
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||||
|
app: {{ template "podinfo.name" . }}
|
||||||
|
annotations:
|
||||||
|
"helm.sh/hook": test
|
||||||
|
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||||
|
sidecar.istio.io/inject: "false"
|
||||||
|
linkerd.io/inject: disabled
|
||||||
|
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: fault
|
||||||
|
image: alpine:3.11
|
||||||
|
command: ['/bin/sh']
|
||||||
|
args: ['-c', 'exit 1']
|
||||||
|
restartPolicy: Never
|
||||||
|
{{- end }}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v1
|
apiVersion: batch/v1
|
||||||
kind: Pod
|
kind: Job
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ template "podinfo.fullname" . }}-grpc-test-{{ randAlphaNum 5 | lower }}
|
name: {{ template "podinfo.fullname" . }}-grpc-test-{{ randAlphaNum 5 | lower }}
|
||||||
labels:
|
labels:
|
||||||
@@ -14,9 +14,11 @@ metadata:
|
|||||||
linkerd.io/inject: disabled
|
linkerd.io/inject: disabled
|
||||||
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
||||||
spec:
|
spec:
|
||||||
containers:
|
template:
|
||||||
- name: grpc-health-probe
|
spec:
|
||||||
image: stefanprodan/grpc_health_probe:v0.3.0
|
containers:
|
||||||
command: ['grpc_health_probe']
|
- name: grpc-health-probe
|
||||||
args: ['-addr={{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.grpcPort }}']
|
image: stefanprodan/grpc_health_probe:v0.3.0
|
||||||
restartPolicy: Never
|
command: ['grpc_health_probe']
|
||||||
|
args: ['-addr={{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.grpcPort }}']
|
||||||
|
restartPolicy: Never
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v1
|
apiVersion: batch/v1
|
||||||
kind: Pod
|
kind: Job
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ template "podinfo.fullname" . }}-jwt-test-{{ randAlphaNum 5 | lower }}
|
name: {{ template "podinfo.fullname" . }}-jwt-test-{{ randAlphaNum 5 | lower }}
|
||||||
labels:
|
labels:
|
||||||
@@ -14,16 +14,18 @@ metadata:
|
|||||||
linkerd.io/inject: disabled
|
linkerd.io/inject: disabled
|
||||||
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
||||||
spec:
|
spec:
|
||||||
containers:
|
template:
|
||||||
- name: tools
|
spec:
|
||||||
image: giantswarm/tiny-tools
|
containers:
|
||||||
command:
|
- name: tools
|
||||||
- sh
|
image: giantswarm/tiny-tools
|
||||||
- -c
|
command:
|
||||||
- |
|
- sh
|
||||||
TOKEN=$(curl -sd 'test' ${PODINFO_SVC}/token | jq -r .token) &&
|
- -c
|
||||||
curl -sH "Authorization: Bearer ${TOKEN}" ${PODINFO_SVC}/token/validate | grep test
|
- |
|
||||||
env:
|
TOKEN=$(curl -sd 'test' ${PODINFO_SVC}/token | jq -r .token) &&
|
||||||
- name: PODINFO_SVC
|
curl -sH "Authorization: Bearer ${TOKEN}" ${PODINFO_SVC}/token/validate | grep test
|
||||||
value: "{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.externalPort }}"
|
env:
|
||||||
restartPolicy: Never
|
- name: PODINFO_SVC
|
||||||
|
value: "{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.externalPort }}"
|
||||||
|
restartPolicy: Never
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v1
|
apiVersion: batch/v1
|
||||||
kind: Pod
|
kind: Job
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ template "podinfo.fullname" . }}-service-test-{{ randAlphaNum 5 | lower }}
|
name: {{ template "podinfo.fullname" . }}-service-test-{{ randAlphaNum 5 | lower }}
|
||||||
labels:
|
labels:
|
||||||
@@ -14,15 +14,17 @@ metadata:
|
|||||||
linkerd.io/inject: disabled
|
linkerd.io/inject: disabled
|
||||||
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
||||||
spec:
|
spec:
|
||||||
containers:
|
template:
|
||||||
- name: curl
|
spec:
|
||||||
image: curlimages/curl:7.69.0
|
containers:
|
||||||
command:
|
- name: curl
|
||||||
- sh
|
image: curlimages/curl:7.69.0
|
||||||
- -c
|
command:
|
||||||
- |
|
- sh
|
||||||
curl -s ${PODINFO_SVC}/api/info | grep version
|
- -c
|
||||||
env:
|
- |
|
||||||
- name: PODINFO_SVC
|
curl -s ${PODINFO_SVC}/api/info | grep version
|
||||||
value: "{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.externalPort }}"
|
env:
|
||||||
restartPolicy: Never
|
- name: PODINFO_SVC
|
||||||
|
value: "{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.externalPort }}"
|
||||||
|
restartPolicy: Never
|
||||||
|
|||||||
26
charts/podinfo/templates/tests/timeout.yaml
Normal file
26
charts/podinfo/templates/tests/timeout.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{{- if .Values.faults.test }}
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: {{ template "podinfo.fullname" . }}-fault-test-{{ randAlphaNum 5 | lower }}
|
||||||
|
labels:
|
||||||
|
heritage: {{ .Release.Service }}
|
||||||
|
release: {{ .Release.Name }}
|
||||||
|
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||||
|
app: {{ template "podinfo.name" . }}
|
||||||
|
annotations:
|
||||||
|
"helm.sh/hook": test
|
||||||
|
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||||
|
sidecar.istio.io/inject: "false"
|
||||||
|
linkerd.io/inject: disabled
|
||||||
|
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: fault
|
||||||
|
image: alpine:3.11
|
||||||
|
command: ['/bin/sh']
|
||||||
|
args: ['-c', 'while sleep 3600; do :; done']
|
||||||
|
restartPolicy: Never
|
||||||
|
{{- end }}
|
||||||
@@ -4,6 +4,7 @@ replicaCount: 1
|
|||||||
logLevel: info
|
logLevel: info
|
||||||
backend: #http://backend-podinfo:9898/echo
|
backend: #http://backend-podinfo:9898/echo
|
||||||
backends: []
|
backends: []
|
||||||
|
cache: ""
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
color: "#34577c"
|
color: "#34577c"
|
||||||
@@ -15,13 +16,15 @@ faults:
|
|||||||
error: false
|
error: false
|
||||||
unhealthy: false
|
unhealthy: false
|
||||||
unready: false
|
unready: false
|
||||||
|
testFail: false
|
||||||
|
testTimeout: false
|
||||||
|
|
||||||
h2c:
|
h2c:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
image:
|
image:
|
||||||
repository: stefanprodan/podinfo
|
repository: stefanprodan/podinfo
|
||||||
tag: 3.2.2
|
tag: 3.3.0
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
service:
|
service:
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ func main() {
|
|||||||
fs.Bool("unready", false, "when set, ready state is never reached")
|
fs.Bool("unready", false, "when set, ready state is never reached")
|
||||||
fs.Int("stress-cpu", 0, "number of CPU cores with 100 load")
|
fs.Int("stress-cpu", 0, "number of CPU cores with 100 load")
|
||||||
fs.Int("stress-memory", 0, "MB of data to load into memory")
|
fs.Int("stress-memory", 0, "MB of data to load into memory")
|
||||||
|
fs.String("cache-server", "", "Redis address in the format <host>:<port>")
|
||||||
|
|
||||||
versionFlag := fs.BoolP("version", "v", false, "get version number")
|
versionFlag := fs.BoolP("version", "v", false, "get version number")
|
||||||
|
|
||||||
|
|||||||
32
deploy/README.md
Normal file
32
deploy/README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Deploy demo webapp
|
||||||
|
|
||||||
|
Demo webapp manifests:
|
||||||
|
- [common](webapp/common)
|
||||||
|
- [frontend](webapp/frontend)
|
||||||
|
- [backend](webapp/backend)
|
||||||
|
|
||||||
|
Deploy the demo in `webapp` namespace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f ./webapp/common
|
||||||
|
kubectl apply -f ./webapp/backend
|
||||||
|
kubectl apply -f ./webapp/frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy the demo in the `dev` namespace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kustomize build ./overlays/dev | kubectl apply -f-
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy the demo in the `staging` namespace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kustomize build ./overlays/staging | kubectl apply -f-
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy the demo in the `production` namespace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kustomize build ./overlays/production | kubectl apply -f-
|
||||||
|
```
|
||||||
73
deploy/bases/backend/deployment.yaml
Normal file
73
deploy/bases/backend/deployment.yaml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 3
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
progressDeadlineSeconds: 60
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxUnavailable: 0
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: backend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
prometheus.io/scrape: "true"
|
||||||
|
prometheus.io/port: "9797"
|
||||||
|
labels:
|
||||||
|
app: backend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: backend
|
||||||
|
image: stefanprodan/podinfo:3.3.0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 9898
|
||||||
|
protocol: TCP
|
||||||
|
- name: http-metrics
|
||||||
|
containerPort: 9797
|
||||||
|
protocol: TCP
|
||||||
|
- name: grpc
|
||||||
|
containerPort: 9999
|
||||||
|
protocol: TCP
|
||||||
|
command:
|
||||||
|
- ./podinfo
|
||||||
|
- --port=9898
|
||||||
|
- --port-metrics=9797
|
||||||
|
- --grpc-port=9999
|
||||||
|
- --grpc-service-name=backend
|
||||||
|
- --level=info
|
||||||
|
- --cache-server=cache:6379
|
||||||
|
env:
|
||||||
|
- name: PODINFO_UI_COLOR
|
||||||
|
value: "#34577c"
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/healthz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/readyz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 2000m
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 32Mi
|
||||||
18
deploy/bases/backend/hpa.yaml
Normal file
18
deploy/bases/backend/hpa.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: autoscaling/v2beta2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: backend
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 2
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 99
|
||||||
7
deploy/bases/backend/kustomization.yaml
Normal file
7
deploy/bases/backend/kustomization.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- service.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- hpa.yaml
|
||||||
|
|
||||||
17
deploy/bases/backend/service.yaml
Normal file
17
deploy/bases/backend/service.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: backend
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 9898
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: http
|
||||||
|
- port: 9999
|
||||||
|
targetPort: grpc
|
||||||
|
protocol: TCP
|
||||||
|
name: grpc
|
||||||
57
deploy/bases/cache/deployment.yaml
vendored
Normal file
57
deploy/bases/cache/deployment.yaml
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: cache
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: cache
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: cache
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: redis:6.0.1
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command:
|
||||||
|
- redis-server
|
||||||
|
- "/redis-master/redis.conf"
|
||||||
|
ports:
|
||||||
|
- name: redis
|
||||||
|
containerPort: 6379
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: redis
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- redis-cli
|
||||||
|
- ping
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 128Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 32Mi
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /var/lib/redis
|
||||||
|
name: data
|
||||||
|
- mountPath: /redis-master
|
||||||
|
name: config
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: redis-config
|
||||||
|
items:
|
||||||
|
- key: redis.conf
|
||||||
|
path: redis.conf
|
||||||
9
deploy/bases/cache/kustomization.yaml
vendored
Normal file
9
deploy/bases/cache/kustomization.yaml
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- service.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
configMapGenerator:
|
||||||
|
- name: redis-config
|
||||||
|
files:
|
||||||
|
- redis.conf
|
||||||
4
deploy/bases/cache/redis.conf
vendored
Normal file
4
deploy/bases/cache/redis.conf
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
maxmemory 64mb
|
||||||
|
maxmemory-policy allkeys-lru
|
||||||
|
save ""
|
||||||
|
appendonly no
|
||||||
13
deploy/bases/cache/service.yaml
vendored
Normal file
13
deploy/bases/cache/service.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: cache
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: cache
|
||||||
|
ports:
|
||||||
|
- name: redis
|
||||||
|
port: 6379
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: redis
|
||||||
72
deploy/bases/frontend/deployment.yaml
Normal file
72
deploy/bases/frontend/deployment.yaml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 3
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
progressDeadlineSeconds: 60
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxUnavailable: 0
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: frontend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
prometheus.io/scrape: "true"
|
||||||
|
prometheus.io/port: "9797"
|
||||||
|
labels:
|
||||||
|
app: frontend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: frontend
|
||||||
|
image: stefanprodan/podinfo:3.3.0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 9898
|
||||||
|
protocol: TCP
|
||||||
|
- name: http-metrics
|
||||||
|
containerPort: 9797
|
||||||
|
protocol: TCP
|
||||||
|
- name: grpc
|
||||||
|
containerPort: 9999
|
||||||
|
protocol: TCP
|
||||||
|
command:
|
||||||
|
- ./podinfo
|
||||||
|
- --port=9898
|
||||||
|
- --port-metrics=9797
|
||||||
|
- --level=info
|
||||||
|
- --backend-url=http://backend:9898/echo
|
||||||
|
- --cache-server=cache:6379
|
||||||
|
env:
|
||||||
|
- name: PODINFO_UI_COLOR
|
||||||
|
value: "#34577c"
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/healthz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/readyz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 128Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 32Mi
|
||||||
18
deploy/bases/frontend/hpa.yaml
Normal file
18
deploy/bases/frontend/hpa.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: autoscaling/v2beta2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: frontend
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 4
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 99
|
||||||
7
deploy/bases/frontend/kustomization.yaml
Normal file
7
deploy/bases/frontend/kustomization.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- service.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- hpa.yaml
|
||||||
|
|
||||||
13
deploy/bases/frontend/service.yaml
Normal file
13
deploy/bases/frontend/service.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: frontend
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: http
|
||||||
10
deploy/overlays/dev/kustomization.yaml
Normal file
10
deploy/overlays/dev/kustomization.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: dev
|
||||||
|
resources:
|
||||||
|
- ../../bases/backend
|
||||||
|
- ../../bases/frontend
|
||||||
|
- ../../bases/cache
|
||||||
|
- namespace.yaml
|
||||||
|
transformers:
|
||||||
|
- labels.yaml
|
||||||
10
deploy/overlays/dev/labels.yaml
Normal file
10
deploy/overlays/dev/labels.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: builtin
|
||||||
|
kind: LabelTransformer
|
||||||
|
metadata:
|
||||||
|
name: labels
|
||||||
|
labels:
|
||||||
|
env: dev
|
||||||
|
instance: webapp
|
||||||
|
fieldSpecs:
|
||||||
|
- path: metadata/labels
|
||||||
|
create: true
|
||||||
4
deploy/overlays/dev/namespace.yaml
Normal file
4
deploy/overlays/dev/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: dev
|
||||||
10
deploy/overlays/production/kustomization.yaml
Normal file
10
deploy/overlays/production/kustomization.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: production
|
||||||
|
resources:
|
||||||
|
- ../../bases/backend
|
||||||
|
- ../../bases/frontend
|
||||||
|
- ../../bases/cache
|
||||||
|
- namespace.yaml
|
||||||
|
transformers:
|
||||||
|
- labels.yaml
|
||||||
10
deploy/overlays/production/labels.yaml
Normal file
10
deploy/overlays/production/labels.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: builtin
|
||||||
|
kind: LabelTransformer
|
||||||
|
metadata:
|
||||||
|
name: labels
|
||||||
|
labels:
|
||||||
|
env: production
|
||||||
|
instance: webapp
|
||||||
|
fieldSpecs:
|
||||||
|
- path: metadata/labels
|
||||||
|
create: true
|
||||||
4
deploy/overlays/production/namespace.yaml
Normal file
4
deploy/overlays/production/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: production
|
||||||
10
deploy/overlays/staging/kustomization.yaml
Normal file
10
deploy/overlays/staging/kustomization.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: staging
|
||||||
|
resources:
|
||||||
|
- ../../bases/backend
|
||||||
|
- ../../bases/frontend
|
||||||
|
- ../../bases/cache
|
||||||
|
- namespace.yaml
|
||||||
|
transformers:
|
||||||
|
- labels.yaml
|
||||||
10
deploy/overlays/staging/labels.yaml
Normal file
10
deploy/overlays/staging/labels.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: builtin
|
||||||
|
kind: LabelTransformer
|
||||||
|
metadata:
|
||||||
|
name: labels
|
||||||
|
labels:
|
||||||
|
env: staging
|
||||||
|
instance: webapp
|
||||||
|
fieldSpecs:
|
||||||
|
- path: metadata/labels
|
||||||
|
create: true
|
||||||
4
deploy/overlays/staging/namespace.yaml
Normal file
4
deploy/overlays/staging/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: staging
|
||||||
74
deploy/webapp/backend/deployment.yaml
Normal file
74
deploy/webapp/backend/deployment.yaml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
namespace: webapp
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 3
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
progressDeadlineSeconds: 60
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxUnavailable: 0
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: backend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
prometheus.io/scrape: "true"
|
||||||
|
prometheus.io/port: "9797"
|
||||||
|
labels:
|
||||||
|
app: backend
|
||||||
|
spec:
|
||||||
|
serviceAccountName: webapp
|
||||||
|
containers:
|
||||||
|
- name: backend
|
||||||
|
image: stefanprodan/podinfo:3.3.0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 9898
|
||||||
|
protocol: TCP
|
||||||
|
- name: http-metrics
|
||||||
|
containerPort: 9797
|
||||||
|
protocol: TCP
|
||||||
|
- name: grpc
|
||||||
|
containerPort: 9999
|
||||||
|
protocol: TCP
|
||||||
|
command:
|
||||||
|
- ./podinfo
|
||||||
|
- --port=9898
|
||||||
|
- --port-metrics=9797
|
||||||
|
- --grpc-port=9999
|
||||||
|
- --grpc-service-name=backend
|
||||||
|
- --level=info
|
||||||
|
env:
|
||||||
|
- name: PODINFO_UI_COLOR
|
||||||
|
value: "#34577c"
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/healthz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/readyz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 2000m
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 32Mi
|
||||||
19
deploy/webapp/backend/hpa.yaml
Normal file
19
deploy/webapp/backend/hpa.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: autoscaling/v2beta2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
namespace: webapp
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: backend
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 2
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 99
|
||||||
18
deploy/webapp/backend/service.yaml
Normal file
18
deploy/webapp/backend/service.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
namespace: webapp
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: backend
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 9898
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: http
|
||||||
|
- port: 9999
|
||||||
|
targetPort: grpc
|
||||||
|
protocol: TCP
|
||||||
|
name: grpc
|
||||||
4
deploy/webapp/common/namespace.yaml
Normal file
4
deploy/webapp/common/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: webapp
|
||||||
29
deploy/webapp/common/reconciler-rbac.yaml
Normal file
29
deploy/webapp/common/reconciler-rbac.yaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: reconciler
|
||||||
|
namespace: webapp
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: reconciler
|
||||||
|
namespace: webapp
|
||||||
|
rules:
|
||||||
|
- apiGroups: ['*']
|
||||||
|
resources: ['*']
|
||||||
|
verbs: ['*']
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: reconciler
|
||||||
|
namespace: webapp
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: reconciler
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: reconciler
|
||||||
|
namespace: webapp
|
||||||
5
deploy/webapp/common/service-account.yaml
Normal file
5
deploy/webapp/common/service-account.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: webapp
|
||||||
|
namespace: webapp
|
||||||
73
deploy/webapp/frontend/deployment.yaml
Normal file
73
deploy/webapp/frontend/deployment.yaml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
namespace: webapp
|
||||||
|
spec:
|
||||||
|
minReadySeconds: 3
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
progressDeadlineSeconds: 60
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxUnavailable: 0
|
||||||
|
type: RollingUpdate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: frontend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
prometheus.io/scrape: "true"
|
||||||
|
prometheus.io/port: "9797"
|
||||||
|
labels:
|
||||||
|
app: frontend
|
||||||
|
spec:
|
||||||
|
serviceAccountName: webapp
|
||||||
|
containers:
|
||||||
|
- name: frontend
|
||||||
|
image: stefanprodan/podinfo:3.3.0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 9898
|
||||||
|
protocol: TCP
|
||||||
|
- name: http-metrics
|
||||||
|
containerPort: 9797
|
||||||
|
protocol: TCP
|
||||||
|
- name: grpc
|
||||||
|
containerPort: 9999
|
||||||
|
protocol: TCP
|
||||||
|
command:
|
||||||
|
- ./podinfo
|
||||||
|
- --port=9898
|
||||||
|
- --port-metrics=9797
|
||||||
|
- --level=info
|
||||||
|
- --backend-url=http://backend:9898/echo
|
||||||
|
env:
|
||||||
|
- name: PODINFO_UI_COLOR
|
||||||
|
value: "#34577c"
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/healthz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- podcli
|
||||||
|
- check
|
||||||
|
- http
|
||||||
|
- localhost:9898/readyz
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 128Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 32Mi
|
||||||
19
deploy/webapp/frontend/hpa.yaml
Normal file
19
deploy/webapp/frontend/hpa.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: autoscaling/v2beta2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
namespace: webapp
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: backend
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 4
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 99
|
||||||
14
deploy/webapp/frontend/service.yaml
Normal file
14
deploy/webapp/frontend/service.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
namespace: webapp
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: frontend
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: http
|
||||||
7
go.mod
7
go.mod
@@ -10,17 +10,18 @@ require (
|
|||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/fatih/color v1.7.0
|
github.com/fatih/color v1.7.0
|
||||||
github.com/fsnotify/fsnotify v1.4.7
|
github.com/fsnotify/fsnotify v1.4.7
|
||||||
github.com/go-chi/chi v4.0.3+incompatible // indirect
|
github.com/go-chi/chi v4.1.1+incompatible // indirect
|
||||||
|
github.com/gomodule/redigo v1.8.1
|
||||||
github.com/gorilla/mux v1.7.4
|
github.com/gorilla/mux v1.7.4
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/hashicorp/go-getter v1.4.1
|
github.com/hashicorp/go-getter v1.4.1
|
||||||
github.com/prometheus/client_golang v1.5.1
|
github.com/prometheus/client_golang v1.5.1
|
||||||
github.com/spf13/cobra v0.0.6
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.6.2
|
github.com/spf13/viper v1.6.2
|
||||||
github.com/swaggo/http-swagger v0.0.0-20190614090009-c2865af9083e
|
github.com/swaggo/http-swagger v0.0.0-20190614090009-c2865af9083e
|
||||||
github.com/swaggo/swag v1.6.5
|
github.com/swaggo/swag v1.6.5
|
||||||
go.uber.org/zap v1.10.0
|
go.uber.org/zap v1.15.0
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
|
||||||
google.golang.org/grpc v1.23.0
|
google.golang.org/grpc v1.23.0
|
||||||
)
|
)
|
||||||
|
|||||||
38
go.sum
38
go.sum
@@ -52,6 +52,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
|||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
@@ -71,8 +72,8 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB
|
|||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
github.com/go-chi/chi v4.0.3+incompatible h1:gakN3pDJnzZN5jqFV2TEdF66rTfKeITyR8qu6ekICEY=
|
github.com/go-chi/chi v4.1.1+incompatible h1:MmTgB0R8Bt/jccxp+t6S/1VGIKdJw5J74CK/c9tTfA4=
|
||||||
github.com/go-chi/chi v4.0.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
github.com/go-chi/chi v4.1.1+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
@@ -111,6 +112,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/gomodule/redigo v1.8.1 h1:Abmo0bI7Xf0IhdIPc7HZQzZcShdnmxeoVuDDtIQp8N8=
|
||||||
|
github.com/gomodule/redigo v1.8.1/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
@@ -123,6 +126,7 @@ github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPg
|
|||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
@@ -233,8 +237,11 @@ github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLk
|
|||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
@@ -248,8 +255,8 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
|||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
|
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||||
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
@@ -268,6 +275,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
|
|||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||||
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
|
||||||
@@ -287,6 +296,7 @@ github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
|
|||||||
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
|
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
@@ -296,12 +306,21 @@ go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
|||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||||
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||||
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||||
|
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@@ -312,7 +331,10 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
|
|||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -385,8 +407,13 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88=
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88=
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE=
|
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE=
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
@@ -421,6 +448,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||||
@@ -437,4 +465,6 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: podinfo
|
name: podinfo
|
||||||
labels:
|
|
||||||
app: podinfo
|
|
||||||
spec:
|
spec:
|
||||||
minReadySeconds: 3
|
minReadySeconds: 3
|
||||||
revisionHistoryLimit: 5
|
revisionHistoryLimit: 5
|
||||||
@@ -25,7 +23,7 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: podinfod
|
- name: podinfod
|
||||||
image: stefanprodan/podinfo:3.2.2
|
image: stefanprodan/podinfo:3.3.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
|
|||||||
@@ -2,3 +2,6 @@ resources:
|
|||||||
- hpa.yaml
|
- hpa.yaml
|
||||||
- deployment.yaml
|
- deployment.yaml
|
||||||
- service.yaml
|
- service.yaml
|
||||||
|
|
||||||
|
commonLabels:
|
||||||
|
app: podinfo
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: podinfo
|
name: podinfo
|
||||||
labels:
|
|
||||||
app: podinfo
|
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|||||||
93
pkg/api/cache.go
Normal file
93
pkg/api/cache.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gomodule/redigo/redis"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cache godoc
|
||||||
|
// @Summary Save payload in cache
|
||||||
|
// @Description writes the posted content in cache and returns the SHA1 hash of the content
|
||||||
|
// @Tags HTTP API
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Router /cache [post]
|
||||||
|
// @Success 200 {object} api.MapResponse
|
||||||
|
func (s *Server) cacheWriteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if s.pool == nil {
|
||||||
|
s.ErrorResponse(w, r, "cache server is offline", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
s.ErrorResponse(w, r, "reading the request body failed", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := hash(string(body))
|
||||||
|
|
||||||
|
conn := s.pool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
_, err = conn.Do("SET", hash, string(body))
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("cache set failed", zap.Error(err))
|
||||||
|
s.ErrorResponse(w, r, "cache set failed", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.JSONResponseCode(w, r, map[string]string{"hash": hash}, http.StatusAccepted)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache godoc
|
||||||
|
// @Summary Get payload from cache
|
||||||
|
// @Description returns the content from cache if key exists
|
||||||
|
// @Tags HTTP API
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Router /cache/{hash} [get]
|
||||||
|
// @Success 200 {string} api.MapResponse
|
||||||
|
func (s *Server) cacheReadHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if s.pool == nil {
|
||||||
|
s.ErrorResponse(w, r, "cache server is offline", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := mux.Vars(r)["hash"]
|
||||||
|
conn := s.pool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
ok, err := redis.Bool(conn.Do("EXISTS", hash))
|
||||||
|
if err != nil || !ok {
|
||||||
|
s.ErrorResponse(w, r, "key not found in cache", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := redis.String(conn.Do("GET", hash))
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("cache get failed", zap.Error(err))
|
||||||
|
s.ErrorResponse(w, r, "cache get failed", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.JSONResponseCode(w, r, map[string]string{"data": data}, http.StatusAccepted)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) startCachePool() {
|
||||||
|
if s.config.CacheServer != "" {
|
||||||
|
s.pool = &redis.Pool{
|
||||||
|
MaxIdle: 3,
|
||||||
|
IdleTimeout: 240 * time.Second,
|
||||||
|
Dial: func() (redis.Conn, error) {
|
||||||
|
return redis.Dial("tcp", s.config.CacheServer)
|
||||||
|
},
|
||||||
|
TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||||
|
_, err := c.Do("PING")
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
// This file was generated by swaggo/swag at
|
// This file was generated by swaggo/swag at
|
||||||
// 2019-08-07 15:52:23.918713 +0300 EEST m=+0.023438272
|
// 2020-05-16 09:49:23.920068 +0300 EEST m=+0.052088436
|
||||||
|
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/template"
|
"github.com/alecthomas/template"
|
||||||
"github.com/swaggo/swag"
|
"github.com/swaggo/swag"
|
||||||
@@ -16,8 +17,8 @@ var doc = `{
|
|||||||
"schemes": {{ marshal .Schemes }},
|
"schemes": {{ marshal .Schemes }},
|
||||||
"swagger": "2.0",
|
"swagger": "2.0",
|
||||||
"info": {
|
"info": {
|
||||||
"description": "Go microservice template for Kubernetes.",
|
"description": "{{.Description}}",
|
||||||
"title": "Podinfo API",
|
"title": "{{.Title}}",
|
||||||
"contact": {
|
"contact": {
|
||||||
"name": "Source Code",
|
"name": "Source Code",
|
||||||
"url": "https://github.com/stefanprodan/podinfo"
|
"url": "https://github.com/stefanprodan/podinfo"
|
||||||
@@ -26,10 +27,10 @@ var doc = `{
|
|||||||
"name": "MIT License",
|
"name": "MIT License",
|
||||||
"url": "https://github.com/stefanprodan/podinfo/blob/master/LICENSE"
|
"url": "https://github.com/stefanprodan/podinfo/blob/master/LICENSE"
|
||||||
},
|
},
|
||||||
"version": "2.0"
|
"version": "{{.Version}}"
|
||||||
},
|
},
|
||||||
"host": "localhost:9898",
|
"host": "{{.Host}}",
|
||||||
"basePath": "/",
|
"basePath": "{{.BasePath}}",
|
||||||
"paths": {
|
"paths": {
|
||||||
"/": {
|
"/": {
|
||||||
"get": {
|
"get": {
|
||||||
@@ -68,7 +69,6 @@ var doc = `{
|
|||||||
"202": {
|
"202": {
|
||||||
"description": "Accepted",
|
"description": "Accepted",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,13 +92,58 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.RuntimeResponse"
|
"$ref": "#/definitions/api.RuntimeResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/cache": {
|
||||||
|
"post": {
|
||||||
|
"description": "writes the posted content in cache and returns the SHA1 hash of the content",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"HTTP API"
|
||||||
|
],
|
||||||
|
"summary": "Save payload in cache",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/cache/{hash}": {
|
||||||
|
"get": {
|
||||||
|
"description": "returns the content from cache if key exists",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"HTTP API"
|
||||||
|
],
|
||||||
|
"summary": "Get payload from cache",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/chunked/{seconds}": {
|
"/chunked/{seconds}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "uses transfer-encoding type chunked to give a partial response and then waits for the specified period",
|
"description": "uses transfer-encoding type chunked to give a partial response and then waits for the specified period",
|
||||||
@@ -116,7 +161,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +184,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +207,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.ArrayResponse"
|
"$ref": "#/definitions/api.ArrayResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +230,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.ArrayResponse"
|
"$ref": "#/definitions/api.ArrayResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,7 +374,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,7 +397,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,7 +443,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.TokenResponse"
|
"$ref": "#/definitions/api.TokenResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -428,7 +466,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.TokenValidationResponse"
|
"$ref": "#/definitions/api.TokenValidationResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -455,7 +492,6 @@ var doc = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,7 +515,6 @@ var doc = `{
|
|||||||
"202": {
|
"202": {
|
||||||
"description": "Accepted",
|
"description": "Accepted",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,11 +525,15 @@ var doc = `{
|
|||||||
"definitions": {
|
"definitions": {
|
||||||
"api.ArrayResponse": {
|
"api.ArrayResponse": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"api.MapResponse": {
|
"api.MapResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": {}
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"api.RuntimeResponse": {
|
"api.RuntimeResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -511,6 +550,9 @@ var doc = `{
|
|||||||
"hostname": {
|
"hostname": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"logo": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -566,11 +608,21 @@ type swaggerInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
var SwaggerInfo = swaggerInfo{Schemes: []string{"http", "https"}}
|
var SwaggerInfo = swaggerInfo{
|
||||||
|
Version: "2.0",
|
||||||
|
Host: "localhost:9898",
|
||||||
|
BasePath: "/",
|
||||||
|
Schemes: []string{"http", "https"},
|
||||||
|
Title: "Podinfo API",
|
||||||
|
Description: "Go microservice template for Kubernetes.",
|
||||||
|
}
|
||||||
|
|
||||||
type s struct{}
|
type s struct{}
|
||||||
|
|
||||||
func (s *s) ReadDoc() string {
|
func (s *s) ReadDoc() string {
|
||||||
|
sInfo := SwaggerInfo
|
||||||
|
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
|
||||||
|
|
||||||
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
||||||
"marshal": func(v interface{}) string {
|
"marshal": func(v interface{}) string {
|
||||||
a, _ := json.Marshal(v)
|
a, _ := json.Marshal(v)
|
||||||
@@ -582,7 +634,7 @@ func (s *s) ReadDoc() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tpl bytes.Buffer
|
var tpl bytes.Buffer
|
||||||
if err := t.Execute(&tpl, SwaggerInfo); err != nil {
|
if err := t.Execute(&tpl, sInfo); err != nil {
|
||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
{
|
{
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
"swagger": "2.0",
|
"swagger": "2.0",
|
||||||
"info": {
|
"info": {
|
||||||
"description": "Go microservice template for Kubernetes.",
|
"description": "Go microservice template for Kubernetes.",
|
||||||
@@ -53,7 +57,6 @@
|
|||||||
"202": {
|
"202": {
|
||||||
"description": "Accepted",
|
"description": "Accepted",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,13 +80,58 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.RuntimeResponse"
|
"$ref": "#/definitions/api.RuntimeResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/cache": {
|
||||||
|
"post": {
|
||||||
|
"description": "writes the posted content in cache and returns the SHA1 hash of the content",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"HTTP API"
|
||||||
|
],
|
||||||
|
"summary": "Save payload in cache",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/cache/{hash}": {
|
||||||
|
"get": {
|
||||||
|
"description": "returns the content from cache if key exists",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"HTTP API"
|
||||||
|
],
|
||||||
|
"summary": "Get payload from cache",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/chunked/{seconds}": {
|
"/chunked/{seconds}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "uses transfer-encoding type chunked to give a partial response and then waits for the specified period",
|
"description": "uses transfer-encoding type chunked to give a partial response and then waits for the specified period",
|
||||||
@@ -101,7 +149,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +172,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,7 +195,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.ArrayResponse"
|
"$ref": "#/definitions/api.ArrayResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,7 +218,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.ArrayResponse"
|
"$ref": "#/definitions/api.ArrayResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,7 +362,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,7 +385,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,7 +431,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.TokenResponse"
|
"$ref": "#/definitions/api.TokenResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,7 +454,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.TokenValidationResponse"
|
"$ref": "#/definitions/api.TokenValidationResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -440,7 +480,6 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,7 +503,6 @@
|
|||||||
"202": {
|
"202": {
|
||||||
"description": "Accepted",
|
"description": "Accepted",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/api.MapResponse"
|
"$ref": "#/definitions/api.MapResponse"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,11 +513,15 @@
|
|||||||
"definitions": {
|
"definitions": {
|
||||||
"api.ArrayResponse": {
|
"api.ArrayResponse": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"api.MapResponse": {
|
"api.MapResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": {}
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"api.RuntimeResponse": {
|
"api.RuntimeResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -496,6 +538,9 @@
|
|||||||
"hostname": {
|
"hostname": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"logo": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
basePath: /
|
basePath: /
|
||||||
definitions:
|
definitions:
|
||||||
api.ArrayResponse:
|
api.ArrayResponse:
|
||||||
items: {}
|
items:
|
||||||
|
type: string
|
||||||
type: array
|
type: array
|
||||||
api.MapResponse:
|
api.MapResponse:
|
||||||
additionalProperties: {}
|
additionalProperties:
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
api.RuntimeResponse:
|
api.RuntimeResponse:
|
||||||
properties:
|
properties:
|
||||||
@@ -16,6 +18,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
hostname:
|
hostname:
|
||||||
type: string
|
type: string
|
||||||
|
logo:
|
||||||
|
type: string
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
num_cpu:
|
num_cpu:
|
||||||
@@ -80,7 +84,6 @@ paths:
|
|||||||
description: Accepted
|
description: Accepted
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Echo
|
summary: Echo
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -96,10 +99,40 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.RuntimeResponse'
|
$ref: '#/definitions/api.RuntimeResponse'
|
||||||
type: object
|
|
||||||
summary: Runtime information
|
summary: Runtime information
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
|
/cache:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: writes the posted content in cache and returns the SHA1 hash of
|
||||||
|
the content
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.MapResponse'
|
||||||
|
summary: Save payload in cache
|
||||||
|
tags:
|
||||||
|
- HTTP API
|
||||||
|
/cache/{hash}:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: returns the content from cache if key exists
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
summary: Get payload from cache
|
||||||
|
tags:
|
||||||
|
- HTTP API
|
||||||
/chunked/{seconds}:
|
/chunked/{seconds}:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -113,7 +146,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Chunked transfer encoding
|
summary: Chunked transfer encoding
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -129,7 +161,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Delay
|
summary: Delay
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -145,7 +176,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.ArrayResponse'
|
$ref: '#/definitions/api.ArrayResponse'
|
||||||
type: object
|
|
||||||
summary: Environment
|
summary: Environment
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -161,7 +191,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.ArrayResponse'
|
$ref: '#/definitions/api.ArrayResponse'
|
||||||
type: object
|
|
||||||
summary: Headers
|
summary: Headers
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -257,7 +286,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Status code
|
summary: Status code
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -274,7 +302,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Upload file
|
summary: Upload file
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -305,7 +332,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.TokenResponse'
|
$ref: '#/definitions/api.TokenResponse'
|
||||||
type: object
|
|
||||||
summary: Generate JWT token
|
summary: Generate JWT token
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -321,7 +347,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.TokenValidationResponse'
|
$ref: '#/definitions/api.TokenValidationResponse'
|
||||||
type: object
|
|
||||||
"401":
|
"401":
|
||||||
description: Unauthorized
|
description: Unauthorized
|
||||||
schema:
|
schema:
|
||||||
@@ -339,7 +364,6 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Version
|
summary: Version
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
@@ -355,8 +379,10 @@ paths:
|
|||||||
description: Accepted
|
description: Accepted
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.MapResponse'
|
$ref: '#/definitions/api.MapResponse'
|
||||||
type: object
|
|
||||||
summary: Echo over websockets
|
summary: Echo over websockets
|
||||||
tags:
|
tags:
|
||||||
- HTTP API
|
- HTTP API
|
||||||
|
schemes:
|
||||||
|
- http
|
||||||
|
- https
|
||||||
swagger: "2.0"
|
swagger: "2.0"
|
||||||
|
|||||||
@@ -3,11 +3,6 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/swaggo/swag"
|
|
||||||
"golang.org/x/net/http2"
|
|
||||||
"golang.org/x/net/http2/h2c"
|
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
@@ -15,13 +10,17 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gomodule/redigo/redis"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
_ "github.com/stefanprodan/podinfo/pkg/api/docs"
|
_ "github.com/stefanprodan/podinfo/pkg/api/docs"
|
||||||
"github.com/stefanprodan/podinfo/pkg/fscache"
|
"github.com/stefanprodan/podinfo/pkg/fscache"
|
||||||
httpSwagger "github.com/swaggo/http-swagger"
|
httpSwagger "github.com/swaggo/http-swagger"
|
||||||
|
"github.com/swaggo/swag"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
"golang.org/x/net/http2/h2c"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @title Podinfo API
|
// @title Podinfo API
|
||||||
@@ -69,12 +68,14 @@ type Config struct {
|
|||||||
Unhealthy bool `mapstructure:"unhealthy"`
|
Unhealthy bool `mapstructure:"unhealthy"`
|
||||||
Unready bool `mapstructure:"unready"`
|
Unready bool `mapstructure:"unready"`
|
||||||
JWTSecret string `mapstructure:"jwt-secret"`
|
JWTSecret string `mapstructure:"jwt-secret"`
|
||||||
|
CacheServer string `mapstructure:"cache-server"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
router *mux.Router
|
router *mux.Router
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
config *Config
|
config *Config
|
||||||
|
pool *redis.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(config *Config, logger *zap.Logger) (*Server, error) {
|
func NewServer(config *Config, logger *zap.Logger) (*Server, error) {
|
||||||
@@ -103,8 +104,10 @@ func (s *Server) registerHandlers() {
|
|||||||
s.router.HandleFunc("/readyz/disable", s.disableReadyHandler).Methods("POST")
|
s.router.HandleFunc("/readyz/disable", s.disableReadyHandler).Methods("POST")
|
||||||
s.router.HandleFunc("/panic", s.panicHandler).Methods("GET")
|
s.router.HandleFunc("/panic", s.panicHandler).Methods("GET")
|
||||||
s.router.HandleFunc("/status/{code:[0-9]+}", s.statusHandler).Methods("GET", "POST", "PUT").Name("status")
|
s.router.HandleFunc("/status/{code:[0-9]+}", s.statusHandler).Methods("GET", "POST", "PUT").Name("status")
|
||||||
s.router.HandleFunc("/store", s.storeWriteHandler).Methods("POST")
|
s.router.HandleFunc("/store", s.storeWriteHandler).Methods("POST", "PUT")
|
||||||
s.router.HandleFunc("/store/{hash}", s.storeReadHandler).Methods("GET").Name("store")
|
s.router.HandleFunc("/store/{hash}", s.storeReadHandler).Methods("GET").Name("store")
|
||||||
|
s.router.HandleFunc("/cache", s.cacheWriteHandler).Methods("POST", "PUT")
|
||||||
|
s.router.HandleFunc("/cache/{hash}", s.cacheReadHandler).Methods("GET").Name("cache")
|
||||||
s.router.HandleFunc("/configs", s.configReadHandler).Methods("GET")
|
s.router.HandleFunc("/configs", s.configReadHandler).Methods("GET")
|
||||||
s.router.HandleFunc("/token", s.tokenGenerateHandler).Methods("POST")
|
s.router.HandleFunc("/token", s.tokenGenerateHandler).Methods("POST")
|
||||||
s.router.HandleFunc("/token/validate", s.tokenValidateHandler).Methods("GET")
|
s.router.HandleFunc("/token/validate", s.tokenValidateHandler).Methods("GET")
|
||||||
@@ -176,6 +179,27 @@ func (s *Server) ListenAndServe(stopCh <-chan struct{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start redis connection pool
|
||||||
|
s.startCachePool()
|
||||||
|
if s.pool != nil {
|
||||||
|
ticker := time.NewTicker(30 * time.Second)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-stopCh:
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
conn := s.pool.Get()
|
||||||
|
_, err := redis.String(conn.Do("PING"))
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("cache server is offline", zap.Error(err), zap.String("server", s.config.CacheServer))
|
||||||
|
}
|
||||||
|
_ = conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// run server in background
|
// run server in background
|
||||||
go func() {
|
go func() {
|
||||||
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||||
@@ -200,6 +224,11 @@ func (s *Server) ListenAndServe(stopCh <-chan struct{}) {
|
|||||||
atomic.StoreInt32(&healthy, 0)
|
atomic.StoreInt32(&healthy, 0)
|
||||||
atomic.StoreInt32(&ready, 0)
|
atomic.StoreInt32(&ready, 0)
|
||||||
|
|
||||||
|
// close cache pool
|
||||||
|
if s.pool != nil {
|
||||||
|
_ = s.pool.Close()
|
||||||
|
}
|
||||||
|
|
||||||
s.logger.Info("Shutting down HTTP server", zap.Duration("timeout", s.config.HttpServerShutdownTimeout))
|
s.logger.Info("Shutting down HTTP server", zap.Duration("timeout", s.config.HttpServerShutdownTimeout))
|
||||||
|
|
||||||
// wait for Kubernetes readiness probe to remove this instance from the load balancer
|
// wait for Kubernetes readiness probe to remove this instance from the load balancer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package version
|
package version
|
||||||
|
|
||||||
var VERSION = "3.2.2"
|
var VERSION = "3.3.0"
|
||||||
var REVISION = "unknown"
|
var REVISION = "unknown"
|
||||||
|
|||||||
Reference in New Issue
Block a user