From 54783a0ee7fe84843a62220cec712701314aded2 Mon Sep 17 00:00:00 2001 From: Andy Teucher Date: Tue, 20 Jan 2026 15:22:29 -0800 Subject: [PATCH 1/2] Script to get status of GH-based hub users --- _scripts/2026-01-20-nmfs-gh-team-cleanup.R | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 _scripts/2026-01-20-nmfs-gh-team-cleanup.R diff --git a/_scripts/2026-01-20-nmfs-gh-team-cleanup.R b/_scripts/2026-01-20-nmfs-gh-team-cleanup.R new file mode 100644 index 0000000..943f99d --- /dev/null +++ b/_scripts/2026-01-20-nmfs-gh-team-cleanup.R @@ -0,0 +1,67 @@ +library(tidyverse) +library(kyber) +library(jupycost) +library(gh) +library(yaml) + +# Get the teams that provide access to the NMFS hub +prod_teams_hub_access <- read_yaml( + "https://raw.githubusercontent.com/2i2c-org/infrastructure/refs/heads/main/config/clusters/nmfs-openscapes/prod.values.yaml" +) |> + pluck( + "jupyterhub", + "hub", + "config", + "GitHubOAuthenticator", + "allowed_organizations" + ) |> + str_remove("^nmfs-openscapes:") + +# Get all NMFS teams and add users +nmfs_teams <- list_teams("nmfs-openscapes", names_only = FALSE) |> + mutate(team = tolower(name), .keep = "unused") |> + mutate( + name = map(slug, \(x) tolower(list_team_members(x, "nmfs-openscapes"))) + ) |> + # join access teams so that we know if/how they are getting access to the hub + left_join( + data.frame(team = prod_teams_hub_access, hub_access = TRUE), + by = "team" + ) |> + mutate(hub_access = replace_na(hub_access, FALSE)) |> + select(team, hub_access, name) + +# Unnest so one row per user per team +nmfs_teams_members <- unnest(nmfs_teams, cols = name) + +# Get directory usage stats from Grafana +dir_size_usage <- user_dir_snapshot( + "https://grafana.nmfs-openscapes.2i2c.cloud", + grafana_token = Sys.getenv("NMFS_GRAFANA_TOKEN") +) |> + filter(namespace == "prod") |> + mutate(name = tolower(directory), .keep = "unused") + +# Join member/team info to home dir info +teams_members_dir_info <- nmfs_teams_members |> + left_join( + dir_size_usage |> + select(name, last_accessed, dirsize_mb), + by = "name" + ) + +# Collapse so one row per user, teams in a comma-separated list +members_team_info <- nmfs_teams_members |> + group_by(name) |> + summarise( + n_teams = length(team), + teams = paste(team, collapse = ";"), + hub_access = any(hub_access) + ) |> + left_join( + dir_size_usage |> + select(name, last_accessed, dirsize_mb), + by = "name" + ) + +write_csv(members_team_info, "nmfs-gh-team-members-access_2026-01-20.csv") From 030a6602efa8b5f012a8d986978af9fb25c959f1 Mon Sep 17 00:00:00 2001 From: Andy Teucher Date: Wed, 21 Jan 2026 12:58:49 -0800 Subject: [PATCH 2/2] standardize names for reliable joining --- _scripts/2026-01-20-nmfs-gh-team-cleanup.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_scripts/2026-01-20-nmfs-gh-team-cleanup.R b/_scripts/2026-01-20-nmfs-gh-team-cleanup.R index 943f99d..58de53d 100644 --- a/_scripts/2026-01-20-nmfs-gh-team-cleanup.R +++ b/_scripts/2026-01-20-nmfs-gh-team-cleanup.R @@ -15,13 +15,14 @@ prod_teams_hub_access <- read_yaml( "GitHubOAuthenticator", "allowed_organizations" ) |> - str_remove("^nmfs-openscapes:") + str_remove("^nmfs-openscapes:") |> + tolower() # Get all NMFS teams and add users nmfs_teams <- list_teams("nmfs-openscapes", names_only = FALSE) |> - mutate(team = tolower(name), .keep = "unused") |> + rename(team = slug) |> mutate( - name = map(slug, \(x) tolower(list_team_members(x, "nmfs-openscapes"))) + name = map(team, \(x) tolower(list_team_members(x, "nmfs-openscapes"))) ) |> # join access teams so that we know if/how they are getting access to the hub left_join(