diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..02e53618 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,17 @@ +name: Install Cosign + +on: + workflow_dispatch: # Esta configuração permite acionar manualmente o workflow + +jobs: + example: + runs-on: ubuntu-latest + permissions: {} + + steps: + - name: Install Cosign + uses: sigstore/cosign-installer@v3.1.1 + + - name: Check install! + run: cosign version + diff --git a/README.md b/README.md new file mode 100644 index 00000000..c443a941 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# LINUXtips-giropops-senhas +Projeto referente ao **Desenvolvimento e Otimização Segura de Aplicações Kubernetes** do **Programa Intensivo em Containers e Kubernetes (PICK)** oferecido pela plataforma https://www.linuxtips.io/ + +## Sobre o projeto +### Aplicação + +A aplicação Giropos Senhas consiste em uma aplicação web que permite ao usuário gerar senhas aleatórias com base em parâmetros como tamanho da senha, incluindo ou não algarismos e/ou caracteres especiais. Ela permite o armazenamento das senhas em memória. + +#### Tecnologias utilizadas: + - Python: https://www.python.org/ + - Flask: https://flask.palletsprojects.com/en/3.0.x/ + - Redis: https://redis.io/ + - Tailwind: https://tailwindui.com/?ref=top + +#### Implantação + As tecnologias utilizadas para a implantação do projeto foram: + - Docker: https://www.docker.com/ + - kind: https://kind.sigs.k8s.io/ + - kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/ + + +#### Sobre a imagem +Para a imagem base foi utilizada uma image distroless da chainguard ([link](https://edu.chainguard.dev/chainguard/chainguard-images/reference/python/)) o que garante uma maior segurança. +![Relatório de Análise de Riscos usando o Trivy](docs/images/trivy.png) + +### Executar a Aplicação usando Docker Compose + +```bash +docker compose -f docker/docker-compose.yaml up -d --force-recreate +``` \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..46a1d4b4 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,21 @@ +FROM cgr.dev/chainguard/python:latest-dev as builder + +WORKDIR /app + +COPY ./giropops-senhas/requirements.txt . + +RUN pip install --upgrade setuptools +RUN pip install -r requirements.txt --user + +FROM cgr.dev/chainguard/python:latest + +COPY --from=builder /home/nonroot/.local/lib/python3.12/site-packages /home/nonroot/.local/lib/python3.12/site-packages + +COPY ./giropops-senhas/ . + +ENV REDIS_HOST=redisdb +ENV FLASK_APP=app.py +# Expose the port +EXPOSE 5000 + +ENTRYPOINT ["python3", "-m", "flask", "run", "--host=0.0.0.0"] diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml new file mode 100644 index 00000000..3d810ee5 --- /dev/null +++ b/docker/docker-compose.yaml @@ -0,0 +1,31 @@ +version: '3' +services: + giropops-senhas: + build: + context: .. + dockerfile: docker/Dockerfile + ports: + - "5000:5000" + networks: + - giropops + volumes: + - strigus:/strigus + + environment: + REDIS_HOST: redisdb + + redisdb: + image: cgr.dev/chainguard/redis:latest + + networks: + - giropops + + volumes: + - strigus:/strigus + +networks: + giropops: + driver: bridge + +volumes: + strigus: diff --git a/docs/images/trivy.png b/docs/images/trivy.png new file mode 100644 index 00000000..1586afa3 Binary files /dev/null and b/docs/images/trivy.png differ diff --git a/app.py b/giropops-senhas/app.py similarity index 100% rename from app.py rename to giropops-senhas/app.py diff --git a/giropops-senhas/requirements.txt b/giropops-senhas/requirements.txt new file mode 100644 index 00000000..74c73a8c --- /dev/null +++ b/giropops-senhas/requirements.txt @@ -0,0 +1,3 @@ +Flask==2.2.5 +redis==4.5.4 +prometheus-client==0.16.0 \ No newline at end of file diff --git a/static/css/output.css b/giropops-senhas/static/css/output.css similarity index 100% rename from static/css/output.css rename to giropops-senhas/static/css/output.css diff --git a/static/css/styles.css b/giropops-senhas/static/css/styles.css similarity index 100% rename from static/css/styles.css rename to giropops-senhas/static/css/styles.css diff --git a/static/js/main.js b/giropops-senhas/static/js/main.js similarity index 100% rename from static/js/main.js rename to giropops-senhas/static/js/main.js diff --git a/static/linuxtips-logo.png b/giropops-senhas/static/linuxtips-logo.png similarity index 100% rename from static/linuxtips-logo.png rename to giropops-senhas/static/linuxtips-logo.png diff --git a/tailwind.config.js b/giropops-senhas/tailwind.config.js similarity index 100% rename from tailwind.config.js rename to giropops-senhas/tailwind.config.js diff --git a/templates/index.html b/giropops-senhas/templates/index.html similarity index 100% rename from templates/index.html rename to giropops-senhas/templates/index.html diff --git a/templates/lista_senhas.html b/giropops-senhas/templates/lista_senhas.html similarity index 100% rename from templates/lista_senhas.html rename to giropops-senhas/templates/lista_senhas.html diff --git a/k8s/app-deployment.yaml b/k8s/app-deployment.yaml new file mode 100644 index 00000000..b3374a63 --- /dev/null +++ b/k8s/app-deployment.yaml @@ -0,0 +1,59 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: giropops-senhas + name: giropops-senhas +spec: + replicas: 2 + selector: + matchLabels: + app: giropops-senhas + template: + metadata: + labels: + app: giropops-senhas + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - giropops-senhas + topologyKey: kubernetes.io/hostname + containers: + - image: giovani0308/giropops-senhas:v2 + name: giropops-senhas + securityContext: + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsNonRoot: true + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" + env: + - name: REDIS_HOST + value: redisdb + ports: + - containerPort: 5000 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 5000 + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /readiness + port: 5000 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/k8s/app-service.yaml b/k8s/app-service.yaml new file mode 100644 index 00000000..73060651 --- /dev/null +++ b/k8s/app-service.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: giropops-senhas + labels: + app: giropops-senhas +spec: + selector: + app: giropops-senhas + ports: + - protocol: TCP + port: 5000 + targetPort: 5000 + name: tcp-app + type: ClusterIP diff --git a/k8s/prometheus-service-account.yaml b/k8s/prometheus-service-account.yaml new file mode 100644 index 00000000..91988a18 --- /dev/null +++ b/k8s/prometheus-service-account.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: prometheus +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: prometheus +rules: + - apiGroups: [""] + resources: + - nodes + - nodes/metrics + - services + - endpoints + - pods + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: + - configmaps + verbs: ["get"] + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: ["get", "list", "watch"] + - nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: prometheus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus +subjects: + - kind: ServiceAccount + name: prometheus + namespace: default diff --git a/k8s/prometheus-service-monitor.yaml b/k8s/prometheus-service-monitor.yaml new file mode 100644 index 00000000..a22f67fe --- /dev/null +++ b/k8s/prometheus-service-monitor.yaml @@ -0,0 +1,13 @@ +ServiceMonitorapiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: prometheus-self + labels: + app: prometheus +spec: + endpoints: + - interval: 30s + port: web + selector: + matchLabels: + app: prometheus diff --git a/k8s/prometheus-service.yaml b/k8s/prometheus-service.yaml new file mode 100644 index 00000000..a7796fa3 --- /dev/null +++ b/k8s/prometheus-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: prometheus + labels: + app: prometheus +spec: + ports: + - name: web + port: 9090 + targetPort: web + selector: + app.kubernetes.io/name: prometheus + sessionAffinity: ClientIP diff --git a/k8s/prometheus.yaml b/k8s/prometheus.yaml new file mode 100644 index 00000000..3fd75238 --- /dev/null +++ b/k8s/prometheus.yaml @@ -0,0 +1,21 @@ +apiVersion: monitoring.coreos.com/v1 +kind: Prometheus +metadata: + name: prometheus + labels: + app: prometheus +spec: + image: quay.io/prometheus/prometheus:v2.22.1 + nodeSelector: + kubernetes.io/os: linux + replicas: 2 + resources: + requests: + memory: 400Mi + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 1000 + serviceAccountName: prometheus + version: v2.22.1 + serviceMonitorSelector: {} diff --git a/k8s/redis-deployment.yaml b/k8s/redis-deployment.yaml new file mode 100644 index 00000000..6bce8354 --- /dev/null +++ b/k8s/redis-deployment.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: redis + name: redis-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - image: cgr.dev/chainguard/redis:latest + name: redis + ports: + - containerPort: 6379 + resources: + limits: + memory: "256Mi" + cpu: "500m" + requests: + memory: "128Mi" + cpu: "250m" diff --git a/k8s/redis-service.yaml b/k8s/redis-service.yaml new file mode 100644 index 00000000..f6cae1c6 --- /dev/null +++ b/k8s/redis-service.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-service +spec: + selector: + app: redis + ports: + - protocol: TCP + port: 6379 + targetPort: 6379 + type: ClusterIP diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5f3d5549..00000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -Flask==2.1.1 -redis==4.5.2 -prometheus-client==0.16.0 \ No newline at end of file