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

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors