---
title: 'Jenkins - WebHook'
disqus: Jenkins
---
Jenkins - Webhook
===
## Contenido
[TOC]
## Webhook
Un **webhook** es un protocolo de software que permite que aplicaciones y servicios envíen mensajes web a otras aplicaciones cada vez que ocurre un determinado evento. La aplicación permite a los usuarios registrar actividades de la aplicación y ciertos eventos bajo condiciones específicas por ejemplo como cuando se crea un nuevo usuario, cuenta, o cuando una orden de comanda electrónica.
Los **webhooks** se entregan a través del protocolo HTTP o HTTPS, generalmente como una solicitud POST a una URL específica. Luego, los datos POST son interpretados por la API de la aplicación receptora, que procesa el objeto solicitado y envía un mensaje a la aplicación de origen para indicar que la operación se ha completado. Los datos enviados suelen utilizar el formato JSON o XML.
Una alternativa a un webhook es un **proceso de sondeo (polling)**. Un proceso de sondeo hace que un programa espere cierta cantidad de tiempo para luego llama a una API para obtener una lista de transacciones recientes, añadiendo las nuevas a una lista y procesándolas. Esto supone que la API proporciona una lista de transacciones recientes.
Jenkins
---
Jenkins es un sistema de integración y entrega continuas. Es una herramienta de código abierto disponible para múltiples arquitecturas que puede manejar cualquier tipo de construcción, pruebas y despliegues gracias a su formato de plugins.
Evolucionó a partir de Hudson, una herramienta de Sun Microsystems que aún continúa en desarrollo pero que pasó a ser de código propietario.
La idea central de Jenkins es la de crear trabajos (a veces denominados jobs) que realicen ciertas operaciones como la compilación, el empaquetado, las pruebas, el despliegue, etc. Se puede diseñar un trabajo que lleve a cabo todas las tareas del pipeline o varios simples con tareas pequeñas y encadenarlos con un trabajo principal. Esta ejecución ha sido uno de los paradigmas fundamentales de Jenkins.
El repositorio de plugins es muy amplio y, de hecho, algunas de las principales características se ofrecen de esta manera. Es más, el primer paso del asistente de configuración de Jenkins es la instalación de los plugins recomendados.
> Sitio oficial de la herramienta [Jenkins](https://www.jenkins.io/)
Gitlab
---
Las herramientas más utilizadas en la industria del desarrollo son GitHub como repositorio de versiones y Jenkins como sistema CICD. Pero estas herramientas no son las únicas disponibles.
Aunque comenzó como una plataforma de alojamiento de código y gestión de problemas de software, GitLab ha evolucionado hasta convertirse en una herramienta que abarca todas las fases del desarrollo. Según su propia documentación, ofrece funcionalidades para gestionar y planificar proyectos, versionar y verificar código, y empaquetar, liberar, monitorizar y proteger aplicaciones.
GitLab está disponible en modalidades SaaS y alojada por el cliente, ambas con el mismo conjunto de funcionalidades. Es de código abierto y, como otros productos del sector, dispone de versiones gratuitas (con menos funcionalidades) y versiones de pago.
> Sitio oficial de la herramienta [Gitlab](https://about.gitlab.com/)
Flujo básico de Webhook
----
```sequence
Operación de Usuario->Gitlab: confirmación de cambio
Note right of Gitlab: disparador de evento
Gitlab-->Jenkins: petición HTTP/POST
Jenkins-->Gitlab:obtención de pipeline
Jenkins-->Gitlab:obtención de proyecto
Jenkins-->Nodo: ejecución de tarea
Nodo-->Jenkins:confirmación operación
Jenkins--Gitlab:confirmación operación (éxito/fallo)
```
Integración Jenkins/Gitlab
===
Prerrequisito
===
1. Token de usuario para acceso al Gitlab
2. Token de usuario para acceso al Jenkins
3. Par de llaves SSH para el Jenkins
4. [Gitlab Plugin (gitlab-plugin) para Jenkins](https://plugins.jenkins.io/gitlab-plugin/)
5. Java, Maven y Git plugins para Jenkins
6. Plugin pipeline-utility-steps para Jenkins
Token de usuario para acceso al Gitlab
---
En configuración es requerida para la integración del Jenkins al Gitlab, mediante esta configuración se podrá notificar el estado de la tarea invocada por el Webhook.
* Ingresar a la cuenta del Gitlab
* Ir a configuración del Usuario

Figura 01: Configuración del Usuario
* Ir a Editar Perfil --> Token de Acceso personal

Figura 02: Vista token de acceso personal
* En esta vista en necesario la configuración de:
* Nombre del token
* Fecha de expiración
* Permiso
* api y read_repository

Figura 03: Token de generacion única
> El token es generado una única vez, es recomendable guardarlo
* ***Agregar token personal en Jenkins***
* Ingresar a la cuenta del Jenkins
* Ir al Panel de Control --> Administrar Jenkins

Figura 04: Panel principal Jenkins
* Ir a Credentials --> System --> Global credentials(unrestricted)

Figura 05: Vista de gestión de credenciales
* Clic sobre el botón Add Credentials para crear una nueva credencial

Figura 06: Vista de creación de credenciales
* Seleccionar el tipo Username and password
* Seleccionar el Scope Global (Jenkins, nodes, items, all child items, etc).
* Ingresar el (username) nombre de usuario propietario del token del Gitlab
* En el campo (password) contraseña agregar el token generado previamente
* Ingresar el ID para identificar la credencial dentro de los Jobs
> Es necesario la creación de dos credenciales, una para la integración de notificación del Jenkins al Gitlab y otra para obtención de los proyectos del repositorio.
> El ejemplo de creación descripta anteriormente corresponde a la credencial para la obtención de los proyectos del repositorio Gitlab.
> Para la generación de la credencial de integración del Jenkins con el Gitla se debe de seguir los mismo pasos.

Figura 07: Vista credencial para integracion
> En la figura se puede observar que el tipo cambia a Gitlab API token.
* Configurar Integración a Gitlab
* Ir a Panel de Control --> Administrar Jenkins, como se muestra en la *Figura 04: Panel principal Jenkins*.
* Ir a Configurar el Sistema al apartado de Gitlab

Figura 08: Vista integración Gitlab
* En este apartodo se debe habilitar la autenticación y seleccionar la credencial a utilizar para el efecto.
Token de usuario para acceso al Jenkins
---
El token es necesario para la comunicación de los eventos generados desde el Gitlab.
* Ir al Jenkins e ingresar con el usuario a utilizar en la integración

Figura 09: Opcione de configuración del Usuario
* Ir a Configurar --> Apartado Clave API Token

Figura 10: Opcione de generación de token
* Clic sobre el botón de Add new Token
> El token es generado una única vez, es recomendable guardarlo
* ***Agregar token personal en Gitlab***
* Ingresar a la cuenta del Gitlab
* Ir al proyecto que requiere la integración con Jenkins
* El ejemplo a utilizar es : `https://gitlab.siare.gov.py/siare-architecture/siare-dto`

Figura 11: Vista proyecto siare-dto
* Opciones de configuración de integración ***Webhook***
* Integrador Gitlab
* Ir al menú lateral opción *integrations*

Figura 12: Vista menú integración
* En el apartado de *Add an integration*, buscar la integración con **Jenkins**
* Seleccionar la integración con Jenkins

Figura 12: Vista formulario integración con Jenkins
* Ingresar los siguientes campos
* Jenkins server URL : `https://jenkins.siare.gov.py/project/pipeCIUsuariosBack`
* Project name : `pipeCIUsuariosBack`
* Username : `<usuario>`
* Password : `<contraseña>`
* Adicionalmente es necesario seleccionar que evento será el disparador del webhook
* Push
* Merge Request
* Tag Push
* Oprimir el botón de Test settings para validar que el Gitlab cuenta con las credenciales y el acceso al servicio del Jenkins
* Caso que la integración es correcta en pantalla se visualizará
* ***Connection successful.***
* Webhook
* Ir al menú lateral opción ***Webhooks***

Figura 13: Vista webhooks
* En este apartado es necesaro la configuración de la URL del proyecto Jenkins al cual se desea notificar cuando haya un evento desde el Gitlab
* La URL tiene el siguiente formato: `https://USERID:APITOKEN@JENKINS_URL/project/YOUR_JOB`
* Ingresar los datos del token y el usuario para la integración y seleccionar el evento que iniciará el llamado.
* Una vez registrado oprimir el botón de test y seleccionar el evento que generará el llamado.
*

Figura 14: Mensaje de confirmación de la configuración
:::warning
Tener en cuenta que tanto la opción de Integración (Http Basic) y Webhooks (userid:token) requiere la utilización del protocolo HTTPS para mayor seguridad.
:::
Par de llaves SSH para el Jenkins (Linux)
---
**Esta opción es requerida caso donde el servidor del Jenkins utilizará el protocolo *Git* para la obtención de los recursos desde el repositorio Gitlab.**
* Abrir una terminal y ejecutar el siguiente comando: `ssh-keygen -t rsa -b 4096 -C "tú correo"`
* El comando requiere ingresar las la ubicación donde será generada las claves y la frase de la contraseña.

Figura 15: Vista de creación de clave SSH
* Agregar la clave SSH al agente ssh-agent
* Esto es necesario caso se haya ingresado la frase de la contraseña
* Ejecutar el siguiente comando: `eval "$(ssh-agent -s)"`,esto permite la inicialización del agente ssh si no esta corriendo actualmente en el equipo
* A continuación ingresar el siguiente comando: `ssh-add ~/.ssh/id_rsa`, esto permite agregar la clave al agente.
* Copiar la clave ssh al servicio del Jenkins
* Ver el apartado de ***Agregar token personal en Jenkins*** y seguir los pasos para la creación de una nueva credencial.

Figura 16: Vista de creación de credenciales
* En este apartado la diferencia es el tipo de credencial (kind) *SSH username with private key* y la asignación de la clave privada.
* Agregar la clave publica al servicio Gitlab
* Ingresar a la cuenta del Gitlab
* Ir a configuración del Usuario
* Ir al menú SSH Keys

Figura 17: Vista de carga de ssh public key
* Ir a una terminal y ejecutar el siguiente comando: `cat ~/.ssh/id_rsa.pub`
* Copia la clave pública del ssh al Gitlab y oprimir el botón ***Add Key***, esto permitirá la conexión entre el Jenkins y Gitlab sin contraseñas.
Utilizando Proyecto Pipeline con Webhooks
===
En el ejemplo a seguir se ha optado por configurar un proyecto de tipo Pipeline.
* Ingresar a la cuenta del Jenkins
* Ir al Panel de Control y oprimir el menú de *Nueva tarea*.
*

Figura 18: Vista nueva tarea
* Seleccionar el tipo *Pipeline* y oprimir el botón **OK**
* En el apartado de *Build Triggers* seleccionar la configuración del disparador.

Figura 19: Vista configuración Build Triggers
* En el apartado de *Pipeline* agregamos el siguiente script:
```shell=
pipeline {
agent any
environment {
EVENT_BRANCH_SOURCE = ''
}
stages {
stage('Clean Workspace'){
steps {
echo "---------------Cleaninig $WORKSPACE BEGIN -----------------------------"
deleteDir() /* clean up our workspace */
}
}
stage('Checkout') {
steps {
script {
checkout([$class: 'GitSCM',
branches: [[name: '*/test']],
userRemoteConfigs: [[url: 'https://gitlab.siare.gov.py/root/pipelines.git',
credentialsId: 'gitlab-token-credentials']],
extensions: [[$class: 'CloneOption', depth: 1, noTags: true, reference: '', shallow: true]],
configureSubmoduleOptions: []])
EVENT_BRANCH_SOURCE = env.gitlabBranch
echo "Branch that triggered the event: ${EVENT_BRANCH_SOURCE}"
}
}
}
stage('Load and Run Script') {
steps {
script {
/* Ejecucion conducional*/
if ("${EVENT_BRANCH_SOURCE}" != null || ${branch} != null){
/* Cargar y ejecutar el script despues de la clonacion */
def pipelineConfig = load "vars/${JOB_NAME}.groovy"
def javaHome = "${ tool 'java17' }"
def mavenHome = "${tool 'maven'}"
/* Puedes pasar parametros si es necesario */
def parameters = [
branch: "${branch}",
repository: "${scmclone}"
]
/* Ejecutar el script cargado con los parametros*/
pipelineConfig.call(parameters)
// build job: pipelineConfig, wait: true
}
}
}
}
}
post {
failure {
updateGitlabCommitStatus name: 'build', state: 'failed'
}
success {
updateGitlabCommitStatus name: 'build', state: 'success'
}
aborted {
updateGitlabCommitStatus name: 'build', state: 'canceled'
}
}
}
```
* El script cuenta con tres parte:
* Obtención del pipeline a utilizar para el Job
* En este apartado se utiliza el stage *Checkout*
```
stage('Checkout') {
steps {
script {
checkout([$class: 'GitSCM',
branches: [[name: '*/test']],
userRemoteConfigs: [
[url: 'https://gitlab.siare.gov.py/root/pipelines.git',
credentialsId: 'gitlab-token-credentials']],
extensions: [[$class: 'CloneOption', depth: 1, noTags: true, reference: '', shallow: true]],
configureSubmoduleOptions: []])
EVENT_BRANCH_SOURCE = env.gitlabBranch
echo "Branch that triggered the event: ${EVENT_BRANCH_SOURCE}"
}
}
}
```
* En este bloque de código se agregan las configuraciones para la obtención del script del pipeline a utilizar.
* URL
* ID de credencial creado previamente
* Ejecutor del script del pipeline con parámetros (caso que el proyecto lo requiera)
```shell=
stage('Load and Run Script') {
steps {
script {
/* Ejecucion conducional*/
if ("${EVENT_BRANCH_SOURCE}" != null || ${branch} != null){
/* Cargar y ejecutar el script despues de la clonacion */
def pipelineConfig = load "vars/${JOB_NAME}.groovy"
def javaHome = "${ tool 'java17' }"
def mavenHome = "${tool 'maven'}"
/* Puedes pasar parametros si es necesario */
def parameters = [
branch: "${branch}",
repository: "${scmclone}"
]
/* Ejecutar el Jenkinsfile cargado con los parametros*/
pipelineConfig.call(parameters)
// build job: pipelineConfig, wait: true
}
}
}
}
```
* En este bloque de código se agrega un paso condicional para evaluar la rama desde donde es lanzada el evento desde el Gitlab y se agregan parámetros necesarios para el script.
* Notificación de la tarea del Job
```shell=
post {
failure {
updateGitlabCommitStatus name: 'build', state: 'failed'
}
success {
updateGitlabCommitStatus name: 'build', state: 'success'
}
aborted {
updateGitlabCommitStatus name: 'build', state: 'canceled'
}
}
```
* En este bloque de código se notifica el estado de ejecución de la tarea al Gitlab

Figura 20: Vista de pipeline ejecutado con éxito den Gitlab
Referencias
---
* Farley, D. y Humble, J. (2010). Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation. Editorial Addison-Wesley Professional
* Pathania N (2017). Pro Continuous Delivery
* Laster, B. (2018). Jenkins 2: Up and Running. (cap. II). O'Reilly.
* https://www.techtarget.com/searchapparchitecture/definition/webhook