Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Githubpeople as bash script #3

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
31 changes: 31 additions & 0 deletions .github/workflows/release_image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: release-image

on:
push:

jobs:
build-image:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}/githubpoeple-sh
tags: |
type=raw,value=latest
- name: Build and push image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vscode/
.env
githubpeople.json
*.pem
!example/*
17 changes: 11 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Dockerfiles may only contain a FROM and the application data.
# For Java applications use /ubi9/openjdk-11-runtime or /ubi9/openjdk-17-runtime as Base Image, for documentation
# please see https://access.redhat.com/documentation/en-us/red_hat_jboss_middleware_for_openshift/3/html/red_hat_java_s2i_for_openshift/
# All other variations must be approved by KM8
FROM debian:12

FROM registry.access.redhat.com/ubi9/openjdk-17-runtime:latest
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install curl -y
RUN apt-get install jq -y
RUN apt-get install ldap-utils -y

COPY target/*.jar /deployments/application.jar
WORKDIR /app
COPY ./githubpeople.sh .

RUN chmod +x ./githubpeople.sh
CMD ["./githubpeople.sh", "githubpeople.json", "200"]
86 changes: 48 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,66 @@
## Customize this file after creating the new REPO and remove this lines.
What to adjust:
* Add the your project or repo name direct under the logo.
* Add a short and long desciption.
* Add links for your final repo to report a bug or request a feature.
* Add list of used technologies.
* If you have, add a roadmap or remove this section.
* Fill up the section for set up and documentation.
* Start in this file only with documentation and link to the docs folder.
* Add more project shields. Use [shields.io](https://shields.io/) with style `for-the-badge`.

## ------- end to remove -------
<!-- add Project Logo, if existing -->

# repo or project name
# githubpeople

[![Made with love by it@M][made-with-love-shield]][itm-opensource]
<!-- feel free to add more shields, style 'for-the-badge' -> see https://shields.io/badges -->

*Add a description from your project here.*
Compares members of a GitHub organization with users from LDAP and a map of GitHub and LDAP usernames.

## Built With

### Built With
The project is built with technologies we use in our projects:

The documentation project is built with technologies we use in our projects:

* *write here the list of used technologies*
* Bash script
* [jq](https://github.com/jqlang/jq)
* ldapsearch from [ldap-utils](https://wiki.debian.org/LDAP/LDAPUtils)

## Roadmap

*if you have a ROADMAP for your project add this here*
See the [open issues](https://github.com/it-at-m/githubpeople/issues) for a full list of proposed features (and known issues).

## Set up

See the [open issues](#) for a full list of proposed features (and known issues).
Build docker image:

```sh
podman build . -t githubpeople
```

## Set up
*how can i start and fly this project*
Run Docker container with environment variables and `githubpeople.json`:

## Documentation
*what insights do you have to tell*

```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
```sh
podman run --env-file ./example/.env -v ./example/githubpeople.json:/app/githubpeople.json githubpeople
```

Optional it is possible to add a `.pem` certificate for LDAP:

```sh
podman run --env-file ./example/.env -v ./example/githubpeople.json:/app/githubpeople.json -v ./example/cert.pem:/app/cert.pem githubpeople
```

use [diagrams](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-diagrams).
## Documentation

In the [it@M](https://github.com/it-at-m/) organization, members can develop with their own, private GitHub account. Therefore, the name of these accounts can be set individually and doesn't match the username in LDAP.

To keep track of the members in the organization, a list (`githubpeople.json`) was created that maps GitHub and LDAP usernames.

In order to check automatically if there are any differences between the organization members, the list and LDAP, this project was started.

It uses a Docker container, which runs a shell script that executes the following steps:

1. Verify that the member list (`githubpeople.json`) exists under the as an argument provided path

1. If a `.pem` certificate was provided, add it to `ldap.conf`

1. Fetch a list of organization members with GitHub's GraphQL API

1. Loop over the entries of `githubpeople.json`, checking if the user is in the organization and concatenating the LDAP usernames to a filter string

1. Search for users in LDAP with `ldapsearch` and the filter string so that only one request to LDAP is needed

1. Again, loop over `githubpeople.json` entries and check if the user is in LDAP

1. Loop over organization members and check if the member is on the `githubpeople.json` list

For each failing check, an error message is printed, and if at least one check fails, the script terminates with error code 1 instead of 0.

## Contributing

Expand All @@ -66,15 +78,13 @@ Don't forget to give the project a star! Thanks again!

More about this in the [CODE_OF_CONDUCT](/CODE_OF_CONDUCT.md) file.


## License

Distributed under the MIT License. See [LICENSE](LICENSE) file for more information.


## Contact

it@M - [email protected]
it@M - [[email protected]](mailto:[email protected])

<!-- project shields / links -->
[made-with-love-shield]: https://img.shields.io/badge/made%20with%20%E2%9D%A4%20by-it%40M-yellow?style=for-the-badge
Expand Down
7 changes: 7 additions & 0 deletions example/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
GITHUBPEOPLE_LDAP_URL=ldaps://example.de:636
GITHUBPEOPLE_LDAP_USER=
GITHUBPEOPLE_LDAP_PASSWORD=
GITHUBPEOPLE_LDAP_BASEDN=DC=example,DC=de

GITHUBPEOPLE_GITHUB_TOKEN=
GITHUBPEOPLE_GITHUB_PROXY=http://proxy.de:80
1 change: 1 addition & 0 deletions example/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Example certificate, replace with real certificate
10 changes: 10 additions & 0 deletions example/githubpeople.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"muenchenUser": "muenchen-u1",
"githubUser": "github-u1"
},
{
"muenchenUser": "muenchen-u2",
"githubUser": "github-u2"
}
]
149 changes: 149 additions & 0 deletions githubpeople.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/bin/bash
fail=0

# Get memberlist from cmd args and verify that the file exists
memberlist=$1
if [ ! -f $1 ]; then
echo "Liste in $memberlist nicht gefunden."
exit $?
fi

maxiterations=$2
if [ ! $2 ]; then
echo "Bitte maximale Anzahl an Iterationen angeben."
exit 1
fi

# Find .pem certificate and load it for ldap
cert=$(find . -type f -name "*.pem" -print -quit)
if [ $cert ] && [ -f $cert ]; then
echo "TLS_CACERT $cert" >> /etc/ldap/ldap.conf
echo "Zertifikat $cert geladen."
else
echo "Kein weiteres Zertifikat geladen."
fi

echo "Lade Daten von GitHub API..."

orgmembers=$(
curl https://api.github.com/graphql -X POST -sS --fail-with-body \
-H "Authorization: Bearer ${GITHUBPEOPLE_GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
--proxy "${GITHUBPEOPLE_GITHUB_PROXY}" \
-d "$(jq -c -n --arg query '
{
organization(login: "it-at-m") {
membersWithRole(first: 100, after: "") {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aktuell werden nur die ersten 100 Personen aus der Organisation ausgelesen, man müsste noch einbauen, dass über after auch weitere ausgeslesen werden können.

nodes {
login
}
}
}
}' '{"query":$query}')"
)

if [ $? -gt 0 ]; then
echo "Fehler beim Laden der Daten von GitHub API."
exit 1
fi

ldapFilter=""

echo "Durchsuche Liste nach Nutzern, die nicht in der GitHub Organisation sind..."

i=0
while true ; do
# Stop if all members in list are checked
if jq .[$i] $memberlist | grep -q null; then
break
fi
if [ $i -gt $maxiterations ]; then
echo "Maximum von $maxiterations Iterationen wurde erreicht."
exit 1
fi

# Get user data from memberlist
muenchenUser=$(jq .[$i].muenchenUser $memberlist | tr -d \")
githubUser=$(jq .[$i].githubUser $memberlist | tr -d \")

ldapFilter="$ldapFilter(cn=$muenchenUser)" # Append user to filter

# Check if githubUser is in organization
if ! echo "$orgmembers" | grep $githubUser > /dev/null 2>&1; then
echo " - Nicht in GitHub Organisation aber in Liste: $muenchenUser / $githubUser"
fail=1
fi

# Go to next member in list
(( i += 1 ))
done

echo "Lade Daten von LDAP..."

# Search ldap for all users in list
ldapResponse=$(ldapsearch -H ${GITHUBPEOPLE_LDAP_URL} -D ${GITHUBPEOPLE_LDAP_USER} -w ${GITHUBPEOPLE_LDAP_PASSWORD} -b ${GITHUBPEOPLE_LDAP_BASEDN} "(|$ldapFilter)" cn)

if [ $? -gt 0 ]; then
echo "Fehler beim Laden der Daten von LDAP."
exit 1
fi

echo "Durchsuche Liste nach Nutzern, die nicht in LDAP sind..."

i=0
while true ; do
# Stop if all members in list are checked
if jq .[$i] $memberlist | grep -q null; then
break
fi
if [ $i -gt $maxiterations ]; then
echo "Maximum von $maxiterations Iterationen wurde erreicht."
exit 1
fi

muenchenUser=$(jq .[$i].muenchenUser $memberlist | tr -d \")
githubUser=$(jq .[$i].githubUser $memberlist | tr -d \")

# Check if user is in LDAP response
if ! echo "$ldapResponse" | grep "cn: $muenchenUser" > /dev/null 2>&1; then
echo " - Nicht in LDAP aber in Liste: $muenchenUser / $githubUser"
fail=1
fi

# Go to next member in list
(( i += 1 ))
done

echo "Durchsuche GitHub Organisation nach Nutern, die nicht in der Liste sind..."

i=0
while true ; do
# Get current username from graphql response
githubUser=$(echo "$orgmembers" | jq .data.organization.membersWithRole.nodes[$i].login | tr -d \")

# Stop if all members of organization are checked
if echo "$githubUser" | grep -q null; then
break
fi
if [ $i -gt $maxiterations ]; then
echo "Maximum von $maxiterations Iterationen wurde erreicht."
exit 1
fi

# Check if user is in list
if ! jq . $memberlist | grep -w $githubUser > /dev/null 2>&1; then
echo " - Nicht in Liste aber in GitHub Organisation: $githubUser"
fail=1
fi

# Go to next member in list
(( i += 1 ))
done

if [ $fail -gt 0 ]; then
echo "Unterschiede gefunden."
exit 1
else
echo "Keine Unterschiede gefunden."
exit 0
fi
Loading