Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: AuditServer CI/CD pipeline
on: [push]
jobs:
Build:
runs-on: ubuntu-latest
env:
GITHUB_LOGIN: ${{ github.actor }}
GITHUB_PACKAGES: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
- run: |
./gradlew build -x test --no-daemon

Test:
runs-on: ubuntu-latest
needs: [Build]
env:
GITHUB_LOGIN: ${{ github.actor }}
GITHUB_PACKAGES: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
- name: Tests
run: |
cp application.properties.sample application.properties
sed -i "s/REPLACEME/${{ secrets.APP_GITHUB_TOKEN }}/g" application.properties
./gradlew test --no-daemon
Deploy:
runs-on: ubuntu-latest
needs: [Test]
env:
GITHUB_LOGIN: ${{ github.actor }}
GITHUB_PACKAGES: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
- name: Build java app
run: |
echo "APP_VERSION=$(grep "version =" build.gradle | awk '{print $3}' | sed "s/'//g")" >> $GITHUB_ENV
./gradlew build -x test --no-daemon
- name: Build docker image
uses: docker/build-push-action@v2
with:
context: .
push: false
tags: audit-server:${{ env.APP_VERSION }}
build-args: VERSION=${{ env.APP_VERSION }}
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.2.0
with:
cluster_name: audit-server
- name: Deploy audit-server helm chart to local cluster
run: |
kind load docker-image audit-server:${{ env.APP_VERSION }} --name audit-server
helm upgrade --install audit-server ./deploy/charts/audit-server \
-f ./deploy/local.yaml \
--set image.tag="${{ env.APP_VERSION }}" \
--set config.githubToken="${{ secrets.APP_GITHUB_TOKEN }}" \
--atomic \
--debug \
--timeout 5m0s
- name: Validate audit-server deployment is successfully serving traffic
run: |
kubectl port-forward svc/audit-server 8000:80 &
sleep 10
curl -f --connect-timeout 3 --retry 10 --retry-delay 5 http://localhost:8000/healthz

66 changes: 66 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
HELP.md
gradle.properties
application.properties
.gradle
# Ignore Gradle build output directory
build/
!**/src/main/**/build/
!**/src/test/**/build/
# Ignora la carpeta de compilados
bin

# Compiled class file
*.class

# Log file
*.log

# Package Files #
*.jar
#excluyo el gradle wrapper de esta regla
!gradle/wrapper/gradle-wrapper.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

#las pruebas harán generar informes excel, que no quiero subir al repositorio remoto
*.xls
/javadoc.xml

### Ficheros que no hay que controlar, para diferentes IDES ###
#Ignoro los directorios que crea el IDE en el espacio de trabajo, que no se suba a git
### STS ###
.gitattributes
.metadata
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM openjdk:16-alpine
ARG VERSION
COPY ./build/libs/auditserver-${VERSION}.jar /app/main.jar
WORKDIR /app
EXPOSE 8080
CMD ["java", "-jar", "main.jar"]
187 changes: 187 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,189 @@
# AuditServer

Servidor de métricas, apoyado en la librería Audit4Improve
## Objetivo

El objetivo de este código es practicar con:
- La gestión de dependencias
- La integración continua
- El despliegue continuo

## Dependencias

Este servidor utiliza la api [Audit4Improve](https://github.com/MIT-FS/Audit4Improve-API), en la que los alumnos han trabajado a lo largo de las prácticas de la asignatura.

Para el entorno local de desarrollo vamos a usar [Kubernetes] en la
máquina local. Para ello, vamos a necesitar installar previamente
[Kind] y [kubectl]. Una vez instalado comprueba que podemos ejecutar el binario:

```shell
kind --version
```

La aplicación se va a desplegar en Kubernetes usando una herramienta de gestión
de la configuración muy liviana llamada [helm], que además es capaz de
automatizar el proceso de release y rollback.

Para ello [descarga e instala helm]. Una vez instalado, comprueba que podemos
ejecutar el binario:

```shell
helm version
```

Para finalizar, necesitaremos un [Personal Access Token de Github] para poder
probar el funcionamiento de la aplicación.

[Kubernetes]: https://kubernetes.io/
[Kind]: https://kind.sigs.k8s.io/docs/user/quick-start#installation
[kubectl]: https://kubernetes.io/docs/tasks/tools/#kubectl
[helm]: https://helm.sh/
[descarga e instala helm]: https://helm.sh/docs/intro/install/
[Personal Access Token de Github]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token

## Desarrollo local

Antes de empezar, necesitamos cargar nuestro Personal Access Token en la shell
donde probemos nuestro código.

```shell
export GITHUB_TOKEN=<token>
```

Para ejecutar el servidor web de en la máquina local, ejecuta el siguiente comando:

```shell
./gradlew bootRun
```

Prueba que el servicio expone un endpoint de metricas en /metricsInfo:

```shell
curl http://localhost:8080/metricsInfo/issues
```

El endpoint debe devolver la siguiente respuesta:

```shell

StatusCode : 200
StatusDescription :
Content : {"name":"issues","unit":"issues","description":"Tareas sin finalizar en el repositorio","type":"java.lang.Integer"}
RawContent : HTTP/1.1 200
Transfer-Encoding: chunked
...
```

### Ejecutar los tests

Para ejecutar los tests unitarios, ejecuta el siguiente comando:

```shell
./gradlew test
```

### Desplegar el entorno local de desarrollo

Para ejecutar el entorno local de desarrollo, ejecuta el siguiente comando:

```shell
./gradlew localenv-up
```

La tarea `localenv` levanta un cluster de Kubernetes y configura de forma
automática el contexto de Kubernetes para que podamos acceder a la API
de Kubernetes de manera local usando `kubectl`. Levantar el entorno local
debe tardar alrededor de 3 minutos.

Finalmente comprobamos que tenemos acceso al cluster de Kubernetes:

```shell
kubectl get po --all-namespaces
```

Deberemos obtener uns salida similar a la siguiente:

```shell
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-558bd4d5db-l8q2g 1/1 Running 0 83s
kube-system coredns-558bd4d5db-rqcbm 1/1 Running 0 84s
kube-system etcd-audit-server-control-plane 1/1 Running 0 94s
kube-system kindnet-glbk7 1/1 Running 0 85s
kube-system kube-apiserver-audit-server-control-plane 1/1 Running 1 94s
kube-system kube-controller-manager-audit-server-control-plane 1/1 Running 0 94s
kube-system kube-proxy-db56r 1/1 Running 0 85s
kube-system kube-scheduler-audit-server-control-plane 1/1 Running 0 94s
local-path-storage local-path-provisioner-547f784dff-vz7c2 1/1 Running 0 83s
```

Cuando hayamos terminado, simplemente borramos el cluster:

```shell
./gradlew localenv-down
```

### Despliegue de la aplicación en el entorno local

Para desplegar la aplicación, ejecuta el siguiente comando:

```shell
./gradlew localenv-deploy
```

Al finalizar, aplicación se encuentra en el `default` namespace, y debe
de haber 1 pod en estado running:

```shell
➜ ~ kubectl get po
NAME READY STATUS RESTARTS AGE
audit-server-7b7f9cbb96-x6kfw 1/1 Running 0 98s
```

Podemos interactuar con la aplicación y simular que recibe peticiones
HTTP haciendo port-forwarding del servicio a nuestra máquina local. De esta
forma, no necesitamos un Load Balancer real en nuestra infraestructura, ni
configuración DNS extra:

```shell
kubectl port-forward svc/audit-server 8000:80
```

Esto abre un tunel al cluster de Kubernetes y expone el puerto 80 del servicio,
que mapea al puerto 8080 del container que se ejecuta en la pod, al puerto 8000
de nuestra máquina local. Y ahora podemos abrir otro terminal y lanzarle
peticiones a nuestro servicio:

```shell
➜ ~ curl http://localhost:8000/healthz
{"healthy":true}
➜ ~ curl http://localhost:8000/metricsInfo/forks
{"name":"forks","unit":"forks","description":"Número de forks, no son los forks de la web","type":"java.lang.Integer"}
```

## Comenzar con Spring Boot para el desarrollo de servicios REST

Enlaces generados automáticamente al crear el esqueleto del servicio en [start.spring.io](https://start.spring.io/)

### Documentación de referencia

For further reference, please consider the following sections:

* [Official Gradle documentation](https://docs.gradle.org)
* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.6.7/gradle-plugin/reference/html/)
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.6.7/gradle-plugin/reference/html/#build-image)
* [Spring Web](https://docs.spring.io/spring-boot/docs/2.6.7/reference/htmlsingle/#boot-features-developing-web-applications)

### Guías

The following guides illustrate how to use some features concretely:

* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)

### Enlaces adicionales

These additional references should also help you:

* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)

4 changes: 4 additions & 0 deletions application.properties.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
app.githubToken=REPLACEME
app.githubApiUrl=https://api.github.com
app.healthzGithubOrg=MIT-FS
app.healthzGithubRepo=AuditServer
Loading