Skip to content

Commit 822ef03

Browse files
feat: adding inventory scripts for self-hosted runners (#82)
* feat: adding inventory scripts for self-hosted runners * feat: adding additional enterprise/organization scripts renaming existing self-hosted runner scripts add hostname parameter
1 parent 0247b9b commit 822ef03

6 files changed

+205
-0
lines changed

gh-cli/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,10 @@ Queries every organization in an enterprise and returns whether the user is a me
653653

654654
Queries the enterprise for all organizations given the specified role (e.g.: which organizations is the user an admin of)
655655

656+
### get-enterprise-self-hosted-runners.sh
657+
658+
Gets a list of self-hosted runners configured at the enterprise level for an enterprise.
659+
656660
### get-enterprise-settings.sh
657661

658662
Gets info about an enterprise using the [EnterpriseOwnerInfo](https://docs.github.com/en/graphql/reference/objects#enterpriseownerinfo) GraphQL object.
@@ -785,6 +789,18 @@ prints all repo names that have a property with name `production` and value `tru
785789

786790
Gets the repository count in an organization
787791

792+
### get-organization-self-hosted-runners-all-runners.sh
793+
794+
Gets a list of all self-hosted runners in an organization, including org-level and repo-level runners.
795+
796+
### get-organization-self-hosted-runners-organization-runners.sh
797+
798+
Gets a list of self-hosted runners configured at the organization level for an organization.
799+
800+
### get-organization-self-hosted-runners-repository-runners.sh
801+
802+
Gets a list of all repo-level self-hosted runners in all repos in an organization.
803+
788804
### get-organization-team-members.sh
789805

790806
Gets the members of a team
@@ -836,6 +852,10 @@ Gets the usage of CODEOWNERS files in all repositories in all organizations in a
836852

837853
Gets the usage of discussions in all repositories in all organizations in a given enterprise (org-wide discussions have to be created in a repository, so this covers that as well)
838854

855+
### get-organizations-self-hosted-runners-organization-runners.sh
856+
857+
Gets a list of self-hosted runners configured at the organization level for all organizations in an enterprise
858+
839859
### get-organizations-settings.sh
840860

841861
Gets the settings for all organizations in an enterprise
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
# gets a list of self-hosted runners configured at the enterprise level for an enterprise
4+
5+
# gh cli's token needs to be able to read at the organization level - run this first if it can't
6+
# gh auth refresh -h github.com -s manage_runners:enterprise
7+
8+
# org owner access (or a custom role with ability to manage self-hosted runners at the org level) is required
9+
10+
if [ -z "$1" ]; then
11+
echo "Usage: $0 <enterprise> <hostname>"
12+
echo "Example: ./get-organization-self-hosted-runners-organization-runners.sh joshjohanning-org github.com > output.tsv"
13+
exit 1
14+
fi
15+
16+
enterprise="$1"
17+
hostname=${2:-"github.com"}
18+
19+
printf "name\tos\tlabels\tstatus\n"
20+
21+
gh api --hostname $hostname --paginate /enterprises/$enterprise/actions/runners --jq '.runners[] | [.name, .os, (.labels | map(.name) | join(",")), .status] | @tsv'
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
3+
# gets a list of all self-hosted runners in an organization, including org-level and repo-level runners
4+
5+
# gh cli's token needs to be able to read at the organization level - run this first if it can't
6+
# gh auth refresh -h github.com -s admin:org
7+
8+
# org owner access (or a custom role with ability to manage self-hosted runners at the org level) is required
9+
10+
if [ -z "$1" ]; then
11+
echo "Usage: $0 <org> <hostname>"
12+
echo "Example: ./get-organization-self-hosted-runners-all-runners.sh joshjohanning-org github.com > output.tsv"
13+
exit 1
14+
fi
15+
16+
org="$1"
17+
hostname=${2:-"github.com"}
18+
19+
printf "type\trepo\tname\tos\tlabels\tstatus\n"
20+
21+
gh api --hostname $hostname --paginate /orgs/$org/actions/runners --jq '.runners[] | ["org", "n/a", .name, .os, (.labels | map(.name) | join(",")), .status] | @tsv'
22+
23+
repos=$(gh api graphql --hostname $hostname --paginate -F org="$org" -f query='query($org: String!$endCursor: String){
24+
organization(login:$org) {
25+
repositories(first:100,after: $endCursor) {
26+
pageInfo {
27+
hasNextPage
28+
endCursor
29+
}
30+
nodes {
31+
owner {
32+
login
33+
}
34+
name
35+
}
36+
}
37+
}
38+
}' --template '{{range .data.organization.repositories.nodes}}{{printf "%s/%s\n" .owner.login .name}}{{end}}')
39+
40+
for repo in $repos; do
41+
gh api --hostname $hostname --paginate /repos/$repo/actions/runners --jq ".runners[] | [\"repo\", \"$repo\", .name, .os, (.labels | map(.name) | join(\",\")), .status] | @tsv"
42+
done
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
# gets a list of self-hosted runners configured at the organization level for an organization
4+
5+
# for repo-level self-hosted runners, see: `get-organization-self-hosted-runners-repository-runners.sh`
6+
# for all self-hosted runners in an org (at org-level and repo-level), see: `get-organization-self-hosted-runners-all-runners.sh`
7+
8+
# gh cli's token needs to be able to read at the organization level - run this first if it can't
9+
# gh auth refresh -h github.com -s admin:org
10+
11+
# org owner access (or a custom role with ability to manage self-hosted runners at the org level) is required
12+
13+
if [ -z "$1" ]; then
14+
echo "Usage: $0 <org> <hostname>"
15+
echo "Example: ./get-organization-self-hosted-runners-organization-runners.sh joshjohanning-org github.com > output.tsv"
16+
exit 1
17+
fi
18+
19+
org="$1"
20+
hostname=${2:-"github.com"}
21+
22+
printf "name\tos\tlabels\tstatus\n"
23+
24+
gh api --hostname $hostname --paginate /orgs/$org/actions/runners --jq '.runners[] | [.name, .os, (.labels | map(.name) | join(",")), .status] | @tsv'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
# gets a list of all repo-level self-hosted runners in all repos in an organization
4+
5+
# for org-level self-hosted runners, see: `get-organization-self-hosted-runners-organization-runners.sh`
6+
# for all self-hosted runners in an org (at org-level and repo-level), see: `get-organization-self-hosted-runners-all-runners.sh`
7+
8+
if [ -z "$1" ]; then
9+
echo "Usage: $0 <org>"
10+
echo "Example: ./get-organization-self-hosted-runners-repository-runners.sh joshjohanning-org github.com > output.tsv"
11+
exit 1
12+
fi
13+
14+
org="$1"
15+
hostname=${2:-"github.com"}
16+
17+
repos=$(gh api graphql --hostname $hostname --paginate -F org="$org" -f query='query($org: String!$endCursor: String){
18+
organization(login:$org) {
19+
repositories(first:100,after: $endCursor) {
20+
pageInfo {
21+
hasNextPage
22+
endCursor
23+
}
24+
nodes {
25+
owner {
26+
login
27+
}
28+
name
29+
}
30+
}
31+
}
32+
}' --template '{{range .data.organization.repositories.nodes}}{{printf "%s/%s\n" .owner.login .name}}{{end}}')
33+
34+
printf "repo\tname\tos\tlabels\tstatus\n"
35+
36+
for repo in $repos; do
37+
gh api --hostname $hostname --paginate /repos/$repo/actions/runners --jq ".runners[] | [\"$repo\", .name, .os, (.labels | map(.name) | join(\",\")), .status] | @tsv"
38+
done
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
3+
# gets a list of self-hosted runners configured at the organization level for all organizations in an enterprise
4+
5+
# for repo-level self-hosted runners, see: `get-self-hosted-runners-in-all-repositories.sh`
6+
# for all self-hosted runners in an org (at org-level and repo-level), see: `get-self-hosted-runners-all-in-organization.sh`
7+
8+
# gh cli's token needs to be able to read at the organization level - run this first if it can't
9+
# gh auth refresh -h github.com -s admin:org -s read:enterprise
10+
11+
# org owner access (or a custom role with ability to manage self-hosted runners at the org level) is required
12+
13+
if [ -z "$1" ]; then
14+
echo "Usage: $0 <enterprise> <hostname>"
15+
echo "Example: ./get-organizations-self-hosted-runners-organization-runners.sh avocado-corp github.com > output.tsv"
16+
exit 1
17+
fi
18+
19+
enterprise="$1"
20+
hostname=${2:-"github.com"}
21+
22+
# Define color codes
23+
RED='\033[0;31m'
24+
NC='\033[0m' # No Color
25+
26+
# we can't do everything in a single call b/c we need to paginate orgs and then paginate repos in the next query (can't do double pagination with gh api)
27+
organizations=$(gh api graphql --hostname $hostname --paginate -f enterpriseName="$enterprise" -f query='
28+
query getEnterpriseOrganizations($enterpriseName: String! $endCursor: String) {
29+
enterprise(slug: $enterpriseName) {
30+
organizations(first: 100, after: $endCursor) {
31+
nodes {
32+
id
33+
login
34+
}
35+
pageInfo {
36+
endCursor
37+
hasNextPage
38+
}
39+
}
40+
}
41+
}' --jq '.data.enterprise.organizations.nodes[].login')
42+
43+
printf "org\tname\tos\tlabels\tstatus\n"
44+
45+
errors=""
46+
47+
for org in $organizations
48+
do
49+
output=$(gh api --hostname $hostname --paginate /orgs/$org/actions/runners --jq ".runners[] | [\"$org\", .name, .os, (.labels | map(.name) | join(\",\")), .status] | @tsv" 2>&1)
50+
51+
if [ $? -ne 0 ]; then
52+
errors="$errors\nError accessing organization: $org:\n$output"
53+
elif [ -n "$output" ]; then
54+
echo "$output"
55+
fi
56+
done
57+
58+
if [ -n "$errors" ]; then
59+
echo -e "${RED}\nErrors encountered:\n$errors${NC}"
60+
fi

0 commit comments

Comments
 (0)