Cuando en GitLab tenemos una estructura compleja de grupos/sub-grupos/proyectos resulta bastante tedioso gestionar los usuarios y saber a qué proyectos tienen acceso determinados usuarios. En este tutorial veremos cómo podemos conseguir la lista completa en toda la jerarquía, para así poder administrar de forma sencilla los usuarios.
Índice
- 1. Introducción
- 2. Entorno
- 3. El código
- 4. Cómo usarlo
- 5. GitLab personal-access-token
- 6. Conclusiones
- 7. Sobre el autor
1. Introducción
GitLab es un potente sistema para gestionar nuestros proyectos de software. Algo que empezó como un simple gestor de repositorios Git hoy en día nos permite no sólo gestionar el repositorio, sino las issues, el pipeline, tablones, …
Sin embargo a pesar de todas sus maravillas, la gestión de usuarios es algo que todavía deja un poco que desear. Si bien tiene mucha potencia porque podemos añadir usuarios como miembros de proyectos, o de grupos y sub-grupos y hay una relación de "herencia" entre todos estos elementos, cuando tenemos una organización grande donde empieza a haber numerosos sub-grupos en estructura de árbol jerárquico, resulta bastante complicado saber en a qué proyectos tiene acceso un usuario ya que no hay forma de buscar toda la jerarquía completa y hay que ir a mano grupo a grupo, sub-grupo a sub-grupo y proyecto a proyecto.
En este tutorial vamos a ver un sencillo programa en Python para recorrer toda esta estructura listando todos los miembros de cada uno de los nodos (grupo, sub-grupo y proyecto), de tal manera que luego podremos hacer simples búsquedas de texto sobre este listado.
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook Pro 15» (3.1 GHz Intel Core i7, 16GB 2133 Mhz LPDDR3, 500GB Flash Storage).
- Sistema Operativo: macOS High Sierra 10.13.3
- Python 2.7.14
- GitLab API v4
3. El código
El código completo con instrucciones para instalarlo y ejecutarlo lo podéis encontrar aquí
También lo pongo a continuación para que veáis lo sencillo que es:
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import requests
headers = {}
indent = 4
def encode(name):
return name.replace('/', '%2F')
def project_members(project_name, indent_level):
url = 'https://gitlab.com/api/v4/projects/{}/members'.format(encode(project_name))
response = requests.get(url, headers=headers)
for member in response.json():
print(' ' * indent * indent_level, 'member -', member['id'], '-', member['username'])
def group_members(group_name, indent_level):
url = 'https://gitlab.com/api/v4/groups/{}/members'.format(encode(group_name))
response = requests.get(url, headers=headers)
for member in response.json():
print(' ' * indent * indent_level, 'member -', member['id'], '-', member['username'])
def group_projects(group_name, indent_level):
url = 'https://gitlab.com/api/v4/groups/{}/projects'.format(encode(group_name))
response = requests.get(url, headers=headers)
for project in response.json():
print(' ' * indent * indent_level, 'project -', project['id'], '-', project['name'], '-', project['visibility'])
project_members(project['path_with_namespace'], indent_level + 1)
def navigate_subgroups(group_name, indent_level):
group_members(group_name, indent_level)
group_projects(group_name, indent_level)
url = 'https://gitlab.com/api/v4/groups/{}/subgroups'.format(encode(group_name))
response = requests.get(url, headers=headers)
for subgroup in response.json():
print(' ' * indent * indent_level, 'subgroup -', subgroup['id'], '-', subgroup['full_path'])
navigate_subgroups(subgroup['full_path'], indent_level + 1)
if __name__ == '__main__':
token = sys.argv[1]
root_group = sys.argv[2]
headers['Private-Token'] = token
print('root group -', root_group)
navigate_subgroups(root_group, 1)
El código básicamente lo que hace es llamar a distintos end-points del API de GitLab de forma recursiva para ir sacando la información sobre los sub-grupos, proyectos y miembros de cada uno.
4. Cómo usarlo
He usado un virtual env de Python para aislar el proyecto y no alterar vuestro sistema operativo. Para crear este virtual env y sus dependencias basta con ejecutar:
./build.sh ; # Will create a Python virtual env and install this module dependencies
. venv/bin/activate ; # Activate the Python virtual env
Ahora para ejecutar nuestro programa podemos hacer:
python -m gitlab
Como vemos le pasamos como primer argumento nuestro <personal-access-token>
(más adelante comentaré cómo conseguir uno), y como segundo argumento el nombre del grupo del que queremos obtener todo el listado de miembros.
Por ejemplo para la estructura siguiente:
organization
John
Laura
sub-group
Sara
Marco
project-1
Pietro
Berta
obtendremos una salida del estilo:
$ python -m gitlab smkcoa34rH_pl23QFKxL organization
root group - organization
member - 837493 - john
member - 208483 - laura
subgroup - 8479355 - organization/sub-group
member - 348473 - sara
member - 483909 - marco
project - 7893921 - devOps - private
member - 1230878 - pietro
member - 499037 - berta
5. GitLab personal-access-token
Para poder acceder al API de GitLab necesitamos unas credenciales, y eso es justamente el <personal-access-token>
, una cadena que nos identifica de forma única para que GitLab sepa que somos nosotros quienes estamos haciendo las llamadas al API.
Para obtener un token de este tipo lo podemos hacer desde la configuración de nuestro perfil: https://gitlab.com/profile/personal_access_tokens.
6. Conclusiones
Actualmente es raro que una aplicación no proporcione un API para acceder a su funcionalidad, por esto en casos donde la interfaz de usuario se nos queda corta es conveniente explorar un poco porque, como en este caso, con unas pocas líneas podemos conseguir resolver nuestro problema.
7. Sobre el autor
Alejandro Pérez García (@alejandropgarci)
Ingeniero en Informática (especialidad de Ingeniería del Software) y Certified ScrumMaster
Socio fundador de Autentia Real Business Solutions S.L. – "Soporte a Desarrollo"
Socio fundador de ThE Audience Megaphone System, S.L. – TEAMS – "Todo el potencial de tus grupos de influencia a tu alcance"