Skip to content

palverdata/devops-usecase

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Teste Técnico — DevOps Junior

Contexto

Você recebeu a especificação de uma API de gerenciamento de tarefas definida via Protocol Buffers (arquivo proto/tasks.proto). Seu trabalho é implementar os dois serviços que compõem esse sistema e containerizá-los.

O arquivo .proto é o único contrato fornecido. Tudo mais — código, Dockerfiles e docker-compose — é sua responsabilidade.


Arquitetura Esperada

  ┌──────────────┐        ┌──────────────────────┐
  │   cliente    │──HTTP─▶│     go-app :8080      │
  │  (curl/etc)  │        │  REST API gateway     │
  └──────────────┘        └──────────┬────────────┘
                                     │ gRPC :50051
                          ┌──────────▼────────────┐
                          │   python-app :50051    │
                          │   gRPC Server          │
                          │   HTTP health :8001    │
                          └───────────────────────┘

O Que Está Fornecido

  • proto/tasks.proto — definição do contrato gRPC. Não altere este arquivo.

Gerando o Código a Partir do .proto

O arquivo .proto precisa ser compilado para gerar as classes e interfaces que você vai usar no código. Cada linguagem tem sua própria ferramenta.

Python

O pacote grpcio-tools já inclui o compilador, sem instalação separada:

pip install grpcio grpcio-tools

python -m grpc_tools.protoc \
  -I proto \
  --python_out=python-app \
  --grpc_python_out=python-app \
  proto/tasks.proto

Isso vai gerar dois arquivos dentro de python-app/:

  • tasks_pb2.py — classes das mensagens (Task, ListTasksRequest, etc.)
  • tasks_pb2_grpc.py — classe base do servidor (TaskServiceServicer) e o stub do cliente

Você vai implementar o servidor herdando de TaskServiceServicer e sobrescrevendo cada método.

Go

Go precisa do compilador protoc instalado separadamente, mais dois plugins:

# instalar o compilador protoc (Ubuntu/Debian)
apt install -y protobuf-compiler

# instalar os plugins Go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

# gerar o código (rode na raiz do repositório)
protoc \
  -I proto \
  --go_out=go-app --go_opt=paths=source_relative \
  --go-grpc_out=go-app --go-grpc_opt=paths=source_relative \
  proto/tasks.proto

Isso vai gerar dentro de go-app/:

  • tasks.pb.go — structs das mensagens
  • tasks_grpc.pb.go — interface do servidor e o client stub

O client stub (NewTaskServiceClient) é o que o Go vai usar para chamar o Python via gRPC.

Dica: adicione os arquivos gerados ao .gitignore ou commite-os — ambas as abordagens são válidas, mas seja consistente e documente sua escolha.


O Que Você Deve Implementar

1. Python App — gRPC Server

Implemente o servidor gRPC definido em tasks.proto. Requisitos:

  • Implementar todos os cinco métodos: ListTasks, GetTask, CreateTask, UpdateTask, DeleteTask
  • Persistência em memória é suficiente (sem banco de dados)
  • Expor um endpoint HTTP /health em uma porta separada (sugerido: 8001) — será usado pelo health check do Docker
  • Logs estruturados em JSON para cada chamada recebida, contendo ao menos: timestamp, método RPC e status

2. Go App — HTTP Gateway

Implemente um serviço HTTP que atua como gateway para o serviço Python. Requisitos:

  • Consumir o Python via gRPC usando o client stub gerado

  • Expor os seguintes endpoints REST:

    Método Rota Descrição
    GET /health Health check
    GET /tasks Lista todas as tarefas
    POST /tasks Cria uma nova tarefa
    GET /tasks/{id} Retorna uma tarefa
    PUT /tasks/{id} Atualiza uma tarefa
    DELETE /tasks/{id} Remove uma tarefa
    GET /summary Resumo: total, completed, pending
  • Exemplo de resposta para GET /summary:

    { "total": 5, "completed": 2, "pending": 3 }
  • Logs estruturados em JSON para cada request HTTP recebido

  • Endereço gRPC do Python configurável via variável de ambiente PYTHON_GRPC_ADDR (ex: python-app:50051)

  • Porta HTTP configurável via PORT (padrão 8080)

3. Dockerfile — Python App

Arquivo: python-app/Dockerfile

  • Imagem base enxuta (ex: python:3.12-slim)
  • Apenas arquivos necessários copiados

4. Dockerfile — Go App

Arquivo: go-app/Dockerfile

  • Multi-stage build obrigatório: stage de compilação separado do stage final
  • Imagem final mínima (ex: gcr.io/distroless/static ou alpine:3)
  • O binário Go compilado é o único artefato da imagem final

5. docker-compose.yml

Arquivo na raiz do repositório orquestrando os dois serviços:

python-app

  • Health check verificando o endpoint /health HTTP
  • Variáveis de ambiente necessárias configuradas

go-app

  • Inicia somente após o python-app estar healthy (depends_on com condition: service_healthy)
  • Variáveis de ambiente necessárias configuradas

Requisitos gerais:

  • Rede bridge customizada e nomeada — serviços se comunicam por nome de serviço, não por IP
  • Limites de recursos: 256MB de memória e 0.5 CPUs por serviço
  • Zero hardcode de configuração (endereços, portas via env vars)

Estrutura Esperada ao Final

.
├── proto/
│   └── tasks.proto       # fornecido — não altere
├── python-app/
│   ├── main.py
│   ├── requirements.txt
│   └── Dockerfile
├── go-app/
│   ├── main.go
│   ├── go.mod
│   └── Dockerfile
├── docker-compose.yml
└── DECISIONS.md          # suas escolhas técnicas documentadas

Validação da Entrega

Após executar docker compose up --build, os seguintes comandos devem funcionar:

# health checks
curl -s http://localhost:8080/health | jq

# criar uma tarefa
curl -s -X POST http://localhost:8080/tasks \
  -H "Content-Type: application/json" \
  -d '{"title":"Deploy em produção","description":"Subir nova versão"}' | jq

# listar e verificar resumo
curl -s http://localhost:8080/tasks   | jq
curl -s http://localhost:8080/summary | jq

Desafios Extras (opcional, em ordem de prioridade)

Implemente na ordem abaixo se sobrar tempo:

1. Observabilidade com Prometheus + Grafana

Adicionar ao docker-compose um Prometheus coletando métricas de ambos os serviços e um Grafana com ao menos um dashboard funcional. Cada serviço deve expor um endpoint /metrics com:

  • Contador de chamadas por operação
  • Histograma de latência por operação

2. Unix Socket

Alterar a comunicação entre Go e Python para um Unix domain socket compartilhado via volume Docker, ao invés de TCP.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors