audit-labs/audit-tools

A collection of scripts, queries, and other goodies you can use in an audit. audit automation compliance evidence scripts

Commit 3812cc8994

3812cc89940661e87b58ef156f6b2d970a086ce2

parent: 6f5865b11e

Unsigned

cmc <hello@cleberg.net> · 2025-05-07 01:49 UTC
committer: <noreply@github.com>

add gitlab pipelines.py script (#5)

* add gitlab pipelines.py script

* Commit from GitHub Actions (Ruff)

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

Layout: unified · split

applications/gitlab/README.org +33
@@ -69,6 +69,39 @@ python ./passwords.py
69# TODO: Need access to a self-hosted version of GitLab to test this out. 69# TODO: Need access to a self-hosted version of GitLab to test this out.
70#+end_src 70#+end_src
71 71
72* =pipelines.py=
73
74#+begin_src sh
75python ./pipelines.py
76#+end_src
77
78#+begin_src text
79Pipeline ID: 1754222228
80 Status: failed
81 Ref: master
82 Created At: 2025-04-06T03:39:15.065Z
83 Duration: N/A seconds
84 Configuration: N/A
85Pipeline ID: 1754221831
86 Status: failed
87 Ref: pr-1
88 Created At: 2025-04-06T03:37:42.333Z
89 Duration: N/A seconds
90 Configuration: N/A
91Pipeline ID: 1754220271
92 Status: failed
93 Ref: pr-1
94 Created At: 2025-04-06T03:33:38.606Z
95 Duration: N/A seconds
96 Configuration: N/A
97Pipeline ID: 1754214637
98 Status: failed
99 Ref: master
100 Created At: 2025-04-06T03:21:39.902Z
101 Duration: N/A seconds
102 Configuration: N/A
103#+end_src
104
72* =provisioning.py= 105* =provisioning.py=
73 106
74\*This script requires an active Premium or Ultimate subscription.*\ 107\*This script requires an active Premium or Ultimate subscription.*\
applications/gitlab/pipelines.py added +59
@@ -0,0 +1,59 @@
1"""
2Review CI/CD pipelines and their configurations for a specific GitLab project.
3"""
4
5import requests
6
7BASE_URL = "https://gitlab.com/api/v4"
8PRIVATE_TOKEN = "your_access_token"
9PROJECT_ID = "project_id"
10TIMEOUT = 30
11
12HEADERS = {"PRIVATE-TOKEN": PRIVATE_TOKEN}
13
14if __name__ == "__main__":
15 page = 1
16 per_page = 100
17
18 while True:
19 response = requests.get(
20 f"{BASE_URL}/projects/{PROJECT_ID}/pipelines",
21 headers=HEADERS,
22 params={"page": page, "per_page": per_page},
23 timeout=TIMEOUT,
24 )
25 if response.status_code == 200:
26 pipelines = response.json()
27 if not pipelines:
28 break
29
30 for pipeline in pipelines:
31 pipeline_id = pipeline["id"]
32 status = pipeline["status"]
33 ref = pipeline["ref"]
34 created_at = pipeline["created_at"]
35 duration = pipeline.get("duration", "N/A")
36
37 print(f"Pipeline ID: {pipeline_id}")
38 print(f" Status: {status}")
39 print(f" Ref: {ref}")
40 print(f" Created At: {created_at}")
41 print(f" Duration: {duration} seconds")
42
43 detail_response = requests.get(
44 f"{BASE_URL}/projects/{PROJECT_ID}/pipelines/{pipeline_id}",
45 headers=HEADERS,
46 timeout=TIMEOUT,
47 )
48 if detail_response.status_code == 200:
49 pipeline_details = detail_response.json()
50 print(f" Configuration: {pipeline_details.get('config', 'N/A')}")
51 else:
52 print(
53 f" Failed to fetch pipeline details: {detail_response.status_code}, {detail_response.text}"
54 )
55
56 page += 1
57 else:
58 print(f"Failed to fetch pipelines: {response.status_code}, {response.text}")
59 break
applications/gitlab/repositories.py +11 −3
@@ -9,7 +9,7 @@ PRIVATE_TOKEN = "your_access_token"
9USER_ID = "your_user_or_group_id" 9USER_ID = "your_user_or_group_id"
10TIMEOUT = 30 10TIMEOUT = 30
11 11
12URL = f"{BASE_URL}/groups/{USER_ID}/projects" # Group URL 12URL = f"{BASE_URL}/groups/{USER_ID}/projects" # Group URL
13# URL = f"{BASE_URL}/users/{USER_ID}/projects" # User URL 13# URL = f"{BASE_URL}/users/{USER_ID}/projects" # User URL
14HEADERS = {"PRIVATE-TOKEN": PRIVATE_TOKEN} 14HEADERS = {"PRIVATE-TOKEN": PRIVATE_TOKEN}
15 15
@@ -20,7 +20,12 @@ def list_projects(user_or_group_id):
20 projects = [] 20 projects = []
21 21
22 while True: 22 while True:
23 response = requests.get(URL, headers=HEADERS, timeout=TIMEOUT, params={"page": page, "per_page": PER_PAGE}) 23 response = requests.get(
24 URL,
25 headers=HEADERS,
26 timeout=TIMEOUT,
27 params={"page": page, "per_page": PER_PAGE},
28 )
24 29
25 if response.status_code == 200: 30 if response.status_code == 200:
26 current_projects = response.json() 31 current_projects = response.json()
@@ -29,7 +34,9 @@ def list_projects(user_or_group_id):
29 projects.extend(current_projects) 34 projects.extend(current_projects)
30 page += 1 35 page += 1
31 else: 36 else:
32 print(f"Failed to retrieve projects: {response.status_code} - {response.text}") 37 print(
38 f"Failed to retrieve projects: {response.status_code} - {response.text}"
39 )
33 break 40 break
34 41
35 if projects: 42 if projects:
@@ -39,5 +46,6 @@ def list_projects(user_or_group_id):
39 else: 46 else:
40 print(f"No projects found for ID: {user_or_group_id}.") 47 print(f"No projects found for ID: {user_or_group_id}.")
41 48
49
42if __name__ == "__main__": 50if __name__ == "__main__":
43 list_projects(USER_ID) 51 list_projects(USER_ID)