|
| 1 | +#!/usr/bin/bash |
| 2 | + |
| 3 | +################################################# |
| 4 | +# Migrate All repos in One Org to a Master Org # |
| 5 | +# Used to help consolidate users Orgs # |
| 6 | +# Can run in debug mode to show list of actions # |
| 7 | +# # |
| 8 | +# @admiralAwkbar # |
| 9 | +################################################# |
| 10 | + |
| 11 | +# |
| 12 | +# Legend: |
| 13 | +# This script is used to migrate repos from one organization |
| 14 | +# to a master organization. This is done in org consolidations. |
| 15 | +# It will transfer ownership to the new org. It can also set |
| 16 | +# teams access in master org when the transfer is complete. |
| 17 | +# You just need to set the teams ids in the script |
| 18 | +# To run the script: |
| 19 | +# |
| 20 | +# - Update variables section in script |
| 21 | +# - chmod +x script.sh |
| 22 | +# - export GITHUB_TOKEN=YourGitHubTokenWithAccess |
| 23 | +# - ./script.sh UsersOrg |
| 24 | +# |
| 25 | +# Script can be ran in debug mode as well to show what repos |
| 26 | +# will be migrated |
| 27 | +# |
| 28 | + |
| 29 | +############## |
| 30 | +# Debug Flag # |
| 31 | +############## |
| 32 | +DEBUG=1 # Debug Flag 0=execute 1=report |
| 33 | + |
| 34 | +######## |
| 35 | +# VARS # |
| 36 | +######## |
| 37 | +ORIG_ORG=$1 # Name of the Original GitHub Organization |
| 38 | +UPDATE_TEAMS=1 # Update Teams access 0=skip 1=execute |
| 39 | +MASTER_ORG='' # Name of the master Organization |
| 40 | +#GITHUB_TOKEN='' # Token to authenticate into GitHub |
| 41 | +GITHUB_URL="https://api.github.com" # URL to GitHub |
| 42 | +READ_TEAM='' # ID of the GitHub team with read access |
| 43 | +WRITE_TEAM='' # Team to add with write access to the repos |
| 44 | +ADMIN_TEAM='' # ID of the GitHub team with Admin access |
| 45 | + |
| 46 | +################################# |
| 47 | +# Vars Set During Run of Script # |
| 48 | +################################# |
| 49 | +ORIG_ORG_REPOS= # Array of all the repositories in Organization |
| 50 | +TEAM_IDS="$READ_TEAM,$ADMIN_TEAM" # String of all team ids to add to repos |
| 51 | +ERROR_COUNT='0' # Total errors found |
| 52 | + |
| 53 | +################################################################################ |
| 54 | +####################### SUB ROUTINES BELOW ##################################### |
| 55 | +################################################################################ |
| 56 | +################################################################################ |
| 57 | +#### Function CheckVars ######################################################## |
| 58 | +CheckVars() |
| 59 | +{ |
| 60 | + # Validate we have Original Org name |
| 61 | + if [[ -z $ORIG_ORG ]]; then |
| 62 | + echo "ERROR: No Original Organization given!" |
| 63 | + echo $0 <OriginalOrganizationName> |
| 64 | + exit 1 |
| 65 | + fi |
| 66 | + |
| 67 | + # Validate we have Master Org name |
| 68 | + if [[ -z $MASTER_ORG ]]; then |
| 69 | + echo "ERROR: No MASTER Organization given!" |
| 70 | + echo "Please update scripts internal Variables!" |
| 71 | + exit 1 |
| 72 | + fi |
| 73 | + |
| 74 | + # Validate we have a token to connect |
| 75 | + if [[ -z $GITHUB_TOKEN ]]; then |
| 76 | + echo "ERROR: No GitHub Token given!" |
| 77 | + echo "Please update scripts internal Variables! Or set env var: export GITHUB_TOKEN=YourToken" |
| 78 | + exit 1 |
| 79 | + fi |
| 80 | + |
| 81 | + ################################ |
| 82 | + # Check if were updating teams # |
| 83 | + ################################ |
| 84 | + if [ $UPDATE_TEAMS -eq 0 ]; then |
| 85 | + echo "Skippinig the update of team permissions" |
| 86 | + else |
| 87 | + # Validate we have a team to grant read access |
| 88 | + if [[ -z $READ_TEAM ]]; then |
| 89 | + echo "ERROR: No Read access team given!" |
| 90 | + echo "Please update scripts internal Variables!" |
| 91 | + exit 1 |
| 92 | + fi |
| 93 | + |
| 94 | + # Validate we have a team to grant write access |
| 95 | + if [[ -z $WRITE_TEAM ]]; then |
| 96 | + echo "ERROR: No Write access team given!" |
| 97 | + echo "Please update scripts internal Variables!" |
| 98 | + exit 1 |
| 99 | + fi |
| 100 | + |
| 101 | + # Validate we have a team to grant admin access |
| 102 | + if [[ -z $ADMIN_TEAM ]]; then |
| 103 | + echo "ERROR: No Admin access team given!" |
| 104 | + echo "Please update scripts internal Variables!" |
| 105 | + exit 1 |
| 106 | + fi |
| 107 | + fi |
| 108 | +} |
| 109 | +################################################################################ |
| 110 | +#### Function GetTeamIds ####################################################### |
| 111 | +GetTeamIds() |
| 112 | +{ |
| 113 | + ################################################# |
| 114 | + # Need to get the team id from team name passed # |
| 115 | + ################################################# |
| 116 | + REGEX='^[0-9]+$' |
| 117 | + # Check if team was passed as number |
| 118 | + if [[ $WRITE_TEAM =~ $REGEX ]]; then |
| 119 | + echo "Team ID passed, adding to list" |
| 120 | + TEAM_IDS+=",$WRITE_TEAM" |
| 121 | + else |
| 122 | + echo "Need to convert TeamName into ID" |
| 123 | + TEAM_RESPONSE=$(curl --request GET \ |
| 124 | + --url $GITHUB_URL/orgs/$ORIG_ORG/teams \ |
| 125 | + --header 'accept: application/vnd.github.hellcat-preview+json' \ |
| 126 | + --header "authorization: token $GITHUB_TOKEN") |
| 127 | + |
| 128 | + # Get the team id |
| 129 | + get_team_id() |
| 130 | + { |
| 131 | + echo ${TEAM_RESPONSE} | base64 --decode | jq -r ${1} |
| 132 | + #echo ${TEAM_RESPONSE} | base64 --decode --ignore-garbage | jq -r ${1} # Need ignore garbae on windows machines |
| 133 | + } |
| 134 | + |
| 135 | + # Get the id of the team |
| 136 | + TEAM_ID=$(get_team_id '.id') |
| 137 | + echo "TeamId:[$TEAM_ID]" |
| 138 | + TEAM_IDS+=",$TEAM_ID" |
| 139 | + # Reset the global to the id |
| 140 | + WRITE_TEAM=$TEAM_ID |
| 141 | + fi |
| 142 | +} |
| 143 | +################################################################################ |
| 144 | +#### Function UpdateTeamPermission ############################################# |
| 145 | +UpdateTeamPermission() |
| 146 | +{ |
| 147 | + # need to add the teams permissions to the repo |
| 148 | + REPO_TO_UPDATE_PERMS=$1 |
| 149 | + # https://developer.github.com/v3/teams/#edit-team |
| 150 | + # PUT /teams/:team_id/repos/:owner/:repo |
| 151 | + |
| 152 | + ################################### |
| 153 | + # Update the Read Permission Team # |
| 154 | + ################################### |
| 155 | + echo "-----------------------------------------------------" |
| 156 | + echo "Setting Read Team Permissions" |
| 157 | + curl -s --request PUT \ |
| 158 | + --url $GITHUB_URL/teams/$READ_TEAM/repos/$MASTER_ORG/$REPO_TO_UPDATE_PERMS \ |
| 159 | + --header "authorization: Bearer $GITHUB_TOKEN" \ |
| 160 | + --header 'content-type: application/json' \ |
| 161 | + --header 'application/vnd.github.hellcat-preview+json' \ |
| 162 | + --data \"{\"permission\": \"pull\"}\" |
| 163 | + |
| 164 | + ######################## |
| 165 | + # Check for any errors # |
| 166 | + ######################## |
| 167 | + if [ $? -ne 0 ]; then |
| 168 | + echo "Error! Failed to set permission" |
| 169 | + ((ERROR_COUNT++)) |
| 170 | + fi |
| 171 | + |
| 172 | + #################################### |
| 173 | + # Update the Write Permission Team # |
| 174 | + #################################### |
| 175 | + echo "-----------------------------------------------------" |
| 176 | + echo "Setting Write Team Permissions" |
| 177 | + curl -s --request PUT \ |
| 178 | + --url $GITHUB_URL/teams/$WRITE_TEAM/repos/$MASTER_ORG/$REPO_TO_UPDATE_PERMS \ |
| 179 | + --header "authorization: Bearer $GITHUB_TOKEN" \ |
| 180 | + --header 'content-type: application/json' \ |
| 181 | + --header 'application/vnd.github.hellcat-preview+json' \ |
| 182 | + --data \"{\"permission\": \"push\"}\" |
| 183 | + |
| 184 | + ######################## |
| 185 | + # Check for any errors # |
| 186 | + ######################## |
| 187 | + if [ $? -ne 0 ]; then |
| 188 | + echo "Error! Failed to set permission" |
| 189 | + ((ERROR_COUNT++)) |
| 190 | + fi |
| 191 | + |
| 192 | + #################################### |
| 193 | + # Update the Admin Permission Team # |
| 194 | + #################################### |
| 195 | + echo "-----------------------------------------------------" |
| 196 | + echo "Setting Admin Team Permissions" |
| 197 | + curl -s --request PUT \ |
| 198 | + --url $GITHUB_URL/teams/$ADMIN_TEAM/repos/$MASTER_ORG/$REPO_TO_UPDATE_PERMS \ |
| 199 | + --header "authorization: Bearer $GITHUB_TOKEN" \ |
| 200 | + --header 'content-type: application/json' \ |
| 201 | + --header 'application/vnd.github.hellcat-preview+json' \ |
| 202 | + --data \"{\"permission\": \"admin\"}\" |
| 203 | + |
| 204 | + ######################## |
| 205 | + # Check for any errors # |
| 206 | + ######################## |
| 207 | + if [ $? -ne 0 ]; then |
| 208 | + echo "Error! Failed to set permission" |
| 209 | + ((ERROR_COUNT++)) |
| 210 | + fi |
| 211 | +} |
| 212 | +################################################################################ |
| 213 | +#### Function GetOrigOrgRepos ################################################## |
| 214 | +GetOrigOrgRepos() |
| 215 | +{ |
| 216 | + ############################## |
| 217 | + # Get response with all info # |
| 218 | + ############################## |
| 219 | + echo "-----------------------------------------------------" |
| 220 | + echo "Gathering all repos from Original Organization:[$ORIG_ORG]" |
| 221 | + ORIG_ORG_RESPONSE=$(curl -s --request GET \ |
| 222 | + --url $GITHUB_URL/orgs/$ORIG_ORG/repos \ |
| 223 | + --header "authorization: Bearer $GITHUB_TOKEN" \ |
| 224 | + --header 'content-type: application/json') |
| 225 | + |
| 226 | + ####################################################### |
| 227 | + # Loop through list of repos in original organization # |
| 228 | + ####################################################### |
| 229 | + echo "-----------------------------------------------------" |
| 230 | + echo "Parsing repo names from Original Organization:" |
| 231 | + for orig_repo in $(echo "${ORIG_ORG_RESPONSE}" | jq -r '.[] | @base64'); |
| 232 | + do |
| 233 | + # Pull the name of the repo out |
| 234 | + get_orig_repo_name() |
| 235 | + { |
| 236 | + echo ${orig_repo} | base64 --decode | jq -r ${1} |
| 237 | + #echo ${orig_repo} | base64 --decode --ignore-garbage | jq -r ${1} # Need ignore garbage on windows machines |
| 238 | + } |
| 239 | + |
| 240 | + # Get the name of the repo |
| 241 | + ORIG_REPO_NAME=$(get_orig_repo_name '.name') |
| 242 | + echo "Name:[$ORIG_REPO_NAME]" |
| 243 | + ORIG_ORG_REPOS+=($ORIG_REPO_NAME) |
| 244 | + done |
| 245 | +} |
| 246 | +################################################################################ |
| 247 | +#### Function MigrateRepos ##################################################### |
| 248 | +MigrateRepos() |
| 249 | +{ |
| 250 | + ######################################## |
| 251 | + # Migrate all the repos to the new org # |
| 252 | + ######################################## |
| 253 | + echo "-----------------------------------------------------" |
| 254 | + echo "Migrating Reposities to master Organization:[$MASTER_ORG]" |
| 255 | + for new_repo in ${ORIG_ORG_REPOS[@]}; |
| 256 | + do |
| 257 | + ####################################### |
| 258 | + # Call the single repo to be migrated # |
| 259 | + ####################################### |
| 260 | + if [ $DEBUG -eq 0 ]; then |
| 261 | + if [ $UPDATE_TEAMS -eq 0 ]; then |
| 262 | + ########################################## |
| 263 | + # Migrating repos without updating teams # |
| 264 | + ########################################## |
| 265 | + echo "-----------------------------------------------------" |
| 266 | + echo "Skipping updating teams" |
| 267 | + echo "Migrating Repo:[$new_repo] to:[$MASTER_ORG/$new_repo]" |
| 268 | + ##################################### |
| 269 | + # Call GitHub =API to transfer repo # |
| 270 | + ##################################### |
| 271 | + curl -s --request POST \ |
| 272 | + --url $GITHUB_URL/repos/$ORIG_ORG/$new_repo/transfer \ |
| 273 | + --header "authorization: Bearer $GITHUB_TOKEN" \ |
| 274 | + --header 'content-type: application/json' \ |
| 275 | + --header 'application/vnd.github.nightshade-preview+json' \ |
| 276 | + --data \"{\"new_owner\": \"$MASTER_ORG\"}\" |
| 277 | + |
| 278 | + ######################## |
| 279 | + # Check for any errors # |
| 280 | + ######################## |
| 281 | + if [ $? -ne 0 ]; then |
| 282 | + echo "Error! Failed to migrate repo" |
| 283 | + ((ERROR_COUNT++)) |
| 284 | + fi |
| 285 | + else |
| 286 | + ###################################### |
| 287 | + # Migrating repos and updating teams # |
| 288 | + ###################################### |
| 289 | + echo "-----------------------------------------------------" |
| 290 | + echo "Migrating Repo:[$new_repo] to:[$MASTER_ORG/$new_repo]" |
| 291 | + ##################################### |
| 292 | + # Call GitHub =API to transfer repo # |
| 293 | + ##################################### |
| 294 | + curl -s --request POST \ |
| 295 | + --url $GITHUB_URL/repos/$ORIG_ORG/$new_repo/transfer \ |
| 296 | + --header "authorization: Bearer $GITHUB_TOKEN" \ |
| 297 | + --header 'content-type: application/json' \ |
| 298 | + --header 'application/vnd.github.nightshade-preview+json' \ |
| 299 | + --data \"{\"new_owner\": \"$MASTER_ORG\", \"team_ids\": [ $TEAM_IDS ]}\" |
| 300 | + |
| 301 | + ######################## |
| 302 | + # Check for any errors # |
| 303 | + ######################## |
| 304 | + if [ $? -ne 0 ]; then |
| 305 | + echo "Error! Failed to migrate repo" |
| 306 | + ((ERROR_COUNT++)) |
| 307 | + fi |
| 308 | + |
| 309 | + ########################### |
| 310 | + # Update Team permissions # |
| 311 | + ########################### |
| 312 | + UpdateTeamPermission $new_repo |
| 313 | + fi |
| 314 | + else |
| 315 | + # Debug loop to print results |
| 316 | + echo "DEBUG: Would have moved:[$new_repo] to:[$MASTER_ORG/$new_repo]" |
| 317 | + fi |
| 318 | + done |
| 319 | +} |
| 320 | +################################################################################ |
| 321 | +#### Function Footer ########################################################### |
| 322 | +Footer() |
| 323 | +{ |
| 324 | + #################### |
| 325 | + # Print the footer # |
| 326 | + #################### |
| 327 | + echo "-----------------------------------------------------" |
| 328 | + echo "the script has completed" |
| 329 | + exit $ERROR_COUNT |
| 330 | +} |
| 331 | +################################################################################ |
| 332 | +#### Function Header ########################################################### |
| 333 | +Header() |
| 334 | +{ |
| 335 | + ##################### |
| 336 | + # Print Header Info # |
| 337 | + ##################### |
| 338 | + echo "-----------------------------------------------------" |
| 339 | + echo "-----------------------------------------------------" |
| 340 | + echo "----- Migrate Repos from user Org to Master Org -----" |
| 341 | + echo "-----------------------------------------------------" |
| 342 | + echo "-----------------------------------------------------" |
| 343 | + echo "" |
| 344 | + echo "Migrating All Repositories from Org:[$ORIG_ORG]" |
| 345 | + echo "Moving all Repositories to Org:[$MASTER_ORG]" |
| 346 | + ############## |
| 347 | + # Debug info # |
| 348 | + ############## |
| 349 | + if [ $DEBUG -eq 1 ]; then |
| 350 | + echo "Running in DEBUG mode! Will only report Repositories that will be migrated" |
| 351 | + else |
| 352 | + echo "Running in Execute mode! Will migrate all repositories" |
| 353 | + fi |
| 354 | + ############# |
| 355 | + # Team Info # |
| 356 | + ############# |
| 357 | + if [ $UPDATE_TEAMS -eq 1 ]; then |
| 358 | + echo "Updating Repositories teams when migrating" |
| 359 | + else |
| 360 | + echo "No teams will be assigned during the migration process" |
| 361 | + fi |
| 362 | + echo "" |
| 363 | +} |
| 364 | +################################################################################ |
| 365 | +################################################################################ |
| 366 | +############################## MAIN ############################################ |
| 367 | +################################################################################ |
| 368 | +################################################################################ |
| 369 | + |
| 370 | +####################################################### |
| 371 | +# Checking that all variables were passed in properly # |
| 372 | +####################################################### |
| 373 | +CheckVars |
| 374 | + |
| 375 | +######################################## |
| 376 | +# Get all repositories in Original Org # |
| 377 | +######################################## |
| 378 | +GetOrigOrgRepos |
| 379 | + |
| 380 | +#################################################### |
| 381 | +# Get a list of all teamIds for the repo migration # |
| 382 | +#################################################### |
| 383 | +GetTeamIds |
| 384 | + |
| 385 | +############################################### |
| 386 | +# Migrate Repositories to master organization # |
| 387 | +############################################### |
| 388 | +MigrateRepos |
| 389 | + |
| 390 | +#################### |
| 391 | +# Print the footer # |
| 392 | +#################### |
| 393 | +Footer |
0 commit comments