├── .gitignore ├── LICENSE ├── README.md ├── install_fclone ├── install_gcloud ├── make-tds ├── old ├── sa-gen_2020 ├── sa-gen_2022 └── update-display-name ├── sa-add2group ├── sa-count ├── sa-delete ├── sa-emails ├── sa-gen └── sa-gen-default.conf /.gitignore: -------------------------------------------------------------------------------- 1 | credentials/* 2 | svcaccts/*.json 3 | lib/__pycache__/ 4 | creds/* 5 | sagen.conf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 88lex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### **sagen** 2 | 3 | May 2023 NOTE: `sa-gen` has been updated to 4 | - Create a Google Group if it does not already exist (set in sa-gen.conf) 5 | - Automatically add service account emails to the specified Google Group 6 | - Install gcloud sdk with the `install_gcloud` script 7 | - Edit sa-gen.conf to specify group name, group email, etc. 8 | - If no sa-gen.conf exists then running sa-gen Creates a default sa-gen.conf, then stops. Edit with nano/vim 9 | - Generate a random alphanumeric SUFFIX for your projects (Google needs a unique project name) 10 | - SUFFIX may also be set manually in `sa-gen.conf` if you like 11 | - Prior versions of sa-gen still run, and have been put in the /old directory 12 | 13 | ADDED new scripts 14 | - `make-tds` (from sasync/utils) Preequisite: fclone 15 | - `make-tds` will create as many new Shared Drives/Team Drives as you like 16 | - It uses Mawaya's fclone which you can install with `install_fclone` 17 | - If you specify one existing Shared Drive on the same account then all new Shared Drives/TDs will be created with the same Members and permissions as the existing Shared Drive 18 | 19 | - `sa-add2group` Prerequisite: gcloud sdk 20 | - This script will extract service account emails from json keys in a local folder, 21 | then add the SA emails to a Google group. If the group does not exist it will create the group 22 | 23 | - `sa-count` Prerequisite: gcloud sdk 24 | - This scipt will get a list of all projects in an account and print the 25 | project name along with the number of service accounts per project 26 | 27 | - `sa-delete` Prerequisite: gcloud sdk 28 | - This script will delete all service accounts in a specified project 29 | 30 | - `sa-emails` Prerequisite: jq 31 | - This script will list all service account emails for json keys in a given directory 32 | 33 | 34 | THINGS TO CONSIDER: 35 | - Google accounts generally allow 12, 25 or 50 projects depending on the type of account 36 | - You may request additional projects. But Google has been a little more selective about granting additional projects recently 37 | - Each project may have up to 100 service accounts. If you try to create more than 100 you will see an error 38 | - For each service account you can create and download up to 10 keys. If you try to create more than 10 keys then you will see an error 39 | - Projects can be deleted. But they stay in a kind of deleted-project-bin for ~30 days. After the 30 day period your unused project quota will increase again 40 | - Generally, project names are irrelevant. They can be used by most applications/ecosystems regardless of name 41 | - Service accounts and/or their keys can be deleted. Unlike with projects, deleted service accounts and/or keys can be recreated immediately 42 | - The naming of service accounts and their respective email addresses are, as with projects, generally irrelevant. As long as they are added to a Google Group then you can use them with Shared Drives/Team Drives. 43 | 44 | ======================= 45 | The documentation below is mostly unchanged, but there may be small differences from the prior version (e.g. slight variable names changes). When I have spare time I will update the docs. If anything glaring, please ping me. 46 | 47 | 48 | NOTE: `sagen` has a sister application called [safire]( https://github.com/88lex/safire ), a python app with a number of additional features and better speed. `safire` can be installed via git clone, pip install safire or from Colab. [[ It has been a while since `safire` was updated, whereas sa-gen still works nicely, but more slowly. ]] 49 | 50 | Please see: https://github.com/88lex/sa-guide For more info on sagen, safire and setting up service accounts. 51 | 52 | This script is not enormously difficult, but does require reading carefully and installing/setting up gcloud sdk. 53 | 54 | Usage: `./sa-gen` will run the script using the variables that you insert/edit below. 55 | 56 | CHANGELOG: The updated sagen does exactly what the old version did, except 57 | - Google's back end sometimes lags for a few seconds between creating projects or service accounts and giving the sdk access to see them. 58 | - As a result, sagen now has variable delays for each cycle of creating service accounts and between each 'function'. The functions are: 59 | - Creating a project. If a project exists an ERROR message will tell you. It is non-fatal, ignore it. 60 | - Enabling apis that give the SAs permission to access Google Drive and gsheets. Others can be added manually if you like. 61 | - Creating service accounts (SAs) in each project that has been created. 62 | - Downloading json keys that include a token that allows you to access and act upon Drive and gsheet resources. Guard the keys with your life. 63 | - Creating a members.csv (current) and allmembers.csv (cumulative) list of all SA emails, which can be added to My Drive, a Shared Drive (Team Drive) and/or a gsheet. These emails can be added individualy or in bulk (see Bulk Add to Group). 64 | 65 | For sa-gen to run correctly you MUST first edit sa-gen itself, inserting your own information in the fields described below. 66 | Be sure to run `chmod +x sa-gen` to all the script to execute. 67 | 68 | 69 | This script uses gcloud sdk to create multiple projects and up to 100 service accounts per project. 70 | It also downloads a json file for each service account that is created, putting a copy of the json file into the 71 | directory that you specify in `KEYS_DIR` in the script. 72 | 73 | The script creates a csv file in the `KEYS_DIR` directory that can be used to bulk upload service account emails to a google group, 74 | which can then be added to your Team Drives and/or My Drive folders. This allows you to use service accounts with rclone sync/copy 75 | 76 | If you have already installed `gcloud sdk` please be sure you have initialized the account for which you wish to create projects and service accounts. 77 | 78 | If you have not installed `gcloud sdk` please go to https://cloud.google.com/sdk/docs/quickstarts and follow the instructions to install for your OS, 79 | Once you have installed gcloud sdk be sure to run `gcloud init` and authorize (auth) to the account where you want to create service accounts. 80 | 81 | There are a number of variables that you need to specify to run sa-gen for your own account, and to create service accounts and jsons 82 | that are names the way you want to name them. These variables are described below. The names and numeric ranges are quite flexible - 83 | name them as you like. 84 | 85 | **export KEYS_DIR=/opt/sa/all** 86 | This is the location where you want to store your service account json keys. Please create it before running this script 87 | Note that you can create a maximum of 100 service accounts per project, but you can store all of your json keys in this 88 | directory as long as the json file names do not overlap. 89 | 90 | **export ORGANIZATION_ID="insertyourorganizationID"** 91 | This can be left blank ( "" ) if you have already initialized the organization in gcloud sdk with `gcloud init`. 92 | 93 | However if you want to be certain then you can manually replace it with your own ORGANIZATION_ID. It is a numeric ID, rather than your account/domain name. 94 | The easiest way find your own ORGANIZATION ID is to use the console where you have installed `gcloud sdk` and type the command `gcloud organizations list`. 95 | This will show you your DISPLAY_NAME, ID, and DIRECTORY_CUSTOMER_ID. The 12 digit number in the middle is your ORGANIZATION_ID. Insert that 96 | number in the script. 97 | 98 | If for some reason you cannot find the ORGANIZATION_ID using the gcloud sdk you can also go to https://console.cloud.google.com/iam-admin/settings. 99 | On that screen go to the top. Choose `Select Project`, then in the popup choose `Select From` and choose your account/domain name. You should see 100 | a column titled ID. The 12 digit number next to your account/domain name is the ORGANIZATION_ID. 101 | 102 | NOTE: DO NOT USE UPPER CASE, spaces or non-alphanumeric symbols. The GROUP_NAME and PROJECT_BASE_NAME that you use below MUST be lower-case alphanumeric characters (a-z, 0-9, - or _ are okay). 103 | 104 | **export GROUP_NAME=mygroup@mydomain.com** 105 | This is the name of the group that you will share your team drives or my drive folders with. 106 | Normally this will be in the format `some_group_name@googlegroups.com` or `mygroup@mydomain.com` 107 | You can create the group by going to `https://admin.google.com/ac/groups`. 108 | 109 | **export PROJECT_BASE_NAME=myprojectbasename** 110 | This is the base name for a project created with this script. It will be appended with the number of each project 111 | as they are created. For example, a base of 'sasync' will create projects called `sasync1`, `sasync2` and so on. 112 | You should choose a base name likely to be unique to your organisation. 113 | NOTE: If using a domain that you share with others, then use a name other than `sasync` as sa-gen will fail if that project name has already been used. 114 | 115 | **export FIRST_PROJECT_NUM=1** 116 | **export LAST_PROJECT_NUM=2** 117 | These are the starting and ending numbers that are appended to the project name. As noted above, a base name of `sasync` and first number of `1` will create projects `sasync1`, `sasync2` until the LAST_PROJECT_NUM . 118 | 119 | Use as many projects as you like, within allowable limits. Paid gsuite accounts can create a max of 50 accounts, but can apply for more. 120 | Free accounts can create up to 12 projects. 121 | 122 | It is a good idea to NOT delete old projects. Google keeps them for 30 days after deletion and this reduces the number of new projects you can create. 123 | If you have old projects and want to reuse them then it is easier to rename them to fit your pattern above. 124 | 125 | If you have already created projects then it is a good idea to start with the next unused project number. For example, if you have 126 | created 500 jsons in projects sacopy1 through sacopy5 and you want to create 5 more projects then you would set FIRST_PROJECT_NUM=6 and 127 | LAST_PROJECT_NUM=10. 128 | 129 | **export SA_EMAIL_BASE_NAME=sagen** 130 | This is the base name for each service account email created with this script. It will be appended with the number of each service account 131 | as they are created. For example, an email base of 'sagen' along with a project base of 'sasync' will create service accounts with email addresses 132 | in the format sagen1@sasync1.iam.gserviceaccount.com , incrementing up to sagen100@sasync1.iam.gserviceaccount.com. If you have more 133 | than one project then the script will increment SA numbers and project numbers, e.g. sagen101@sasyncy2.iam.gserviceaccount.com and so on. 134 | 135 | **export FIRST_SA_NUM=1** 136 | FIRST_SA_NUM will be the number of the first service account and json file for this batch that you are creating. 137 | If this is your first batch then set FIRST_SA=1. Otherwise set it to your highest SA number+1 138 | 139 | **export NUM_SAS_PER_PROJECT=100** 140 | NUM_SAS_PER_PROJECT is the number of service accounts/SAs that you want to create for each project 141 | 142 | If you have set all of these correctly they you can run `./sa-gen` and it will cycle through creation of your projects and service accounts. 143 | The json files will be in the directory you specified, along with a file called `members.csv` which you can bulk upload to your group. 144 | 145 | **Once you have set the above variables go the command line and run `./sa-gen` . The script will create the projects and service accounts for you.** 146 | 147 | **Please see https://github.com/88lex/sa-guide for further information. Note that sa-guide may not be completely updated, but should provide some help.** 148 | 149 | ***************** 150 | ***************** 151 | 152 | **NOTES:** 153 | Forked from DashLt at https://gist.github.com/DashLt/4c6ff6e9bde4e9bc4a9ed7066c4efba4 and 154 | Forked from mc2squared at https://gist.github.com/mc2squared/01c933a8172a26af88285610a0e5af8d 155 | Borrowed some great ideas from JD at https://gist.github.com/zen-jd/cc6c609b9389443bd7eeac3be8c74710 156 | -------------------------------------------------------------------------------- /install_fclone: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Download the fclone zip file 4 | wget https://github.com/mawaya/rclone/releases/download/fclone-v0.4.1/fclone-v0.4.1-linux-amd64.zip 5 | 6 | # Unzip the fclone zip file 7 | unzip fclone-v0.4.1-linux-amd64.zip 8 | 9 | # Move the fclone binary to /usr/local/bin 10 | sudo mv fclone-v0.4.1-linux-amd64/fclone /usr/local/bin 11 | 12 | # Make the fclone binary executable 13 | sudo chmod +x /usr/local/bin/fclone 14 | 15 | # Add the fclone binary to your PATH 16 | export PATH=$PATH:/usr/local/bin 17 | 18 | # Test that fclone is installed correctly 19 | fclone -V 20 | -------------------------------------------------------------------------------- /install_gcloud: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Installing Google Cloud SDK..." 3 | export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" 4 | echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list 5 | curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - 6 | sudo apt-get update && sudo apt-get install google-cloud-sdk 7 | echo "Google Cloud SDK installation complete." 8 | -------------------------------------------------------------------------------- /make-tds: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This script is a simple wrapper for mawaya's fclone backed command `add-drive` 3 | # Grab the executable from https://github.com/mawaya/rclone/releases and put in /usr/bin/ 4 | # For a couple TDs you can simply use the fclone command manually 5 | # 6 | # `gdrive` is a mydrive or td that has full administrative permissions - used for authentication 7 | # `members` is an existing TD whose members/groups you want to mirror in the new TDs 8 | # `declare -a prefix`` is a common prefix or prefixes for the TDs you want to create [optional] 9 | # `declare -a td` are the non common suffices for the new drives. Keep parentheses and use double quotes 10 | # 11 | # Note: gdrive and members include colon: while prefix and td list do not 12 | # The default entries below would create 10 TDs with the same members/perms as my-td. 13 | # That is, TDs named `goober-001` .. `goober-005` and `gawber-001` .. `gawber-005` 14 | 15 | gdrive="mydrive:" 16 | members="my-td:" 17 | declare -a prefix=("goober" "gawber") 18 | declare -a td=("-001" "-002" "-003" "-004" "-005") 19 | 20 | for j in "${prefix[@]}"; do 21 | for i in "${td[@]}"; do 22 | echo "Creating new TD named $j$i" 23 | fclone backend add-drive $gdrive $j$i --tpslimit=1 -o copy-members=$members 24 | sleep 10s 25 | done 26 | done 27 | 28 | fclone backend lsdrives $gdrive | grep "$prefix" 29 | -------------------------------------------------------------------------------- /old/sa-gen_2020: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Running this script requires gcloud command line tools. To install go to https://cloud.google.com/sdk/docs/quickstarts 3 | # See readme.md to understand the variables used in this script 4 | 5 | export KEYS_DIR=/opt/sa 6 | export ORGANIZATION_ID="insertyourorganizationID" 7 | export GROUP_NAME=mygroup@mydomain.com 8 | export PROJECT_BASE_NAME=myprojectbasename 9 | export FIRST_PROJECT_NUM=1 10 | export LAST_PROJECT_NUM=12 11 | export SA_EMAIL_BASE_NAME=sagen 12 | export FIRST_SA_NUM=1 13 | export NUM_SAS_PER_PROJECT=100 14 | 15 | create_project() { 16 | export PROJECT=$1 17 | gcloud projects create $PROJECT --organization=$ORGANIZATION_ID 18 | gcloud config set project $PROJECT 19 | gcloud services enable drive.googleapis.com 20 | sleep 5s 21 | } 22 | 23 | create_sas() { 24 | let LAST_SA_NUM=$FIRST_SA_NUM+$NUM_SAS_PER_PROJECT 25 | for name in $(seq $FIRST_SA_NUM $LAST_SA_NUM); do 26 | saname="$SA_EMAIL_BASE_NAME""$name" 27 | echo creating service account for $saname 28 | gcloud iam service-accounts create $saname --display-name=$saname 29 | gcloud iam service-accounts keys create $KEYS_DIR/$name.json --iam-account=$saname@$PROJECT.iam.gserviceaccount.com 30 | # NEED to fix syntax for below command to add SA email to group 31 | #gcloud iam service-accounts add-iam-policy-binding "$saname@$PROJECT.iam.gserviceaccount.com" --member="group:$GROUP_NAME" --role="roles/viewer" 32 | echo "$GROUP_NAME,$saname@$PROJECT.iam.gserviceaccount.com,USER,MEMBER" | tee -a $KEYS_DIR/members.csv $KEYS_DIR/allmembers.csv 33 | done 34 | let FIRST_SA_NUM=$FIRST_SA_NUM+100 35 | sleep 5s 36 | } 37 | 38 | main() { 39 | mkdir -p $KEYS_DIR 40 | [ -f $KEYS_DIR/members.csv ] && cat $KEYS_DIR/members.csv >> $KEYS_DIR/allmembers.csv && sort -uo $KEYS_DIR/allmembers.csv $KEYS_DIR/allmembers.csv 41 | echo "Group Email [Required],Member Email,Member Type,Member Role" >$KEYS_DIR/members.csv 42 | for project_num in $(seq $FIRST_PROJECT_NUM $LAST_PROJECT_NUM); do 43 | create_project $PROJECT_BASE_NAME$project_num 44 | create_sas 45 | done 46 | } 47 | 48 | main 49 | -------------------------------------------------------------------------------- /old/sa-gen_2022: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Running this script requires gcloud command line tools. To install go to https://cloud.google.com/sdk/docs/quickstarts 3 | # See readme.md to understand the variables used in this script 4 | 5 | KEYS_DIR=/opt/sa/all # path where you want to store sa JSON files [you will need to add the /all here, most likely] 6 | ORGANIZATION_ID="insertyourorganizationID" # organization ID from gcloud SDK step 7 | GROUP_NAME="mygroup@mydomain.com" # the group [full address as shown] you created previously 8 | PROJECT_BASE_NAME="myprojectbasename" # any unique prefix or the prefix you generated for saltbox 9 | FIRST_PROJECT_NUM=1 10 | LAST_PROJECT_NUM=3 11 | SA_EMAIL_BASE_NAME="insertuniquename" # any unique prefix or the prefix you generated for saltbox 12 | FIRST_SA_NUM=1 13 | NUM_SAS_PER_PROJECT=100 14 | CYCLE_DELAY=0.1s # If issues with Google back end not recognizing SAs increase this number. Set = 0 for no delay 15 | SECTION_DELAY=5s # If issues with Google back end not recognizing SAs increase this number. Set = 0 for no delay 16 | 17 | 18 | create_projects() { 19 | PROJECT="$PROJECT_BASE_NAME$project_num" 20 | echo -e "Creating project = $PROJECT" 21 | set -x 22 | gcloud projects create $PROJECT --organization=$ORGANIZATION_ID 23 | set +x 24 | sleep $CYCLE_DELAY 25 | } 26 | 27 | enable_apis() { 28 | PROJECT="$PROJECT_BASE_NAME$project_num" 29 | echo -e "Enabling apis for project = $PROJECT" 30 | set -x 31 | gcloud config set project $PROJECT 32 | gcloud services enable drive.googleapis.com sheets.googleapis.com \ 33 | admin.googleapis.com cloudresourcemanager.googleapis.com servicemanagement.googleapis.com 34 | set +x 35 | sleep $CYCLE_DELAY 36 | } 37 | 38 | create_sas() { 39 | PROJECT="$PROJECT_BASE_NAME$project_num" 40 | set -x 41 | gcloud config set project $PROJECT 42 | set +x 43 | echo -e "Create service accounts for project = $PROJECT" 44 | let LAST_SA_NUM=$COUNT+$NUM_SAS_PER_PROJECT-1 45 | for name in $(seq $COUNT $LAST_SA_NUM); do 46 | saname="$SA_EMAIL_BASE_NAME""$name" 47 | echo -e "Creating service account number $name in project = $PROJECT ==> $saname@$PROJECT" 48 | set -x 49 | gcloud iam service-accounts create $saname --display-name=$saname 50 | set +x 51 | sleep $CYCLE_DELAY 52 | done 53 | sleep $SECTION_DELAY 54 | SA_COUNT=`gcloud iam service-accounts list | grep gservice | wc -l` 55 | echo -e "Total number of service accounts (SAs) in project $PROJECT = $SA_COUNT" 56 | let COUNT=$COUNT+$NUM_SAS_PER_PROJECT 57 | } 58 | 59 | create_keys() { 60 | PROJECT="$PROJECT_BASE_NAME$project_num" 61 | set -x 62 | gcloud config set project $PROJECT 63 | set +x 64 | echo -e "create json keys for $PROJECT" 65 | TOTAL_JSONS_BEF=`ls $KEYS_DIR | grep ".json" | wc -l` 66 | let LAST_SA_NUM=$COUNT+$NUM_SAS_PER_PROJECT-1 67 | for name in $(seq $COUNT $LAST_SA_NUM); do 68 | saname="$SA_EMAIL_BASE_NAME""$name" 69 | echo -e "Creating json key $name.json in project = $PROJECT for service account = $saname@$PROJECT" 70 | set -x 71 | gcloud iam service-accounts keys create $KEYS_DIR/$name.json --iam-account=$saname@$PROJECT.iam.gserviceaccount.com 72 | set +x 73 | # NEED to fix syntax for below command to add SA email to group 74 | #gcloud iam service-accounts add-iam-policy-binding "$saname@$PROJECT.iam.gserviceaccount.com" --member="group:$GROUP_NAME" --role="roles/editor" 75 | echo "$GROUP_NAME,$saname@$PROJECT.iam.gserviceaccount.com,USER,MEMBER" | tee -a $KEYS_DIR/members.csv $KEYS_DIR/allmembers.csv 76 | sleep $CYCLE_DELAY 77 | done 78 | MEMBER_COUNT=`cat $KEYS_DIR/members.csv | grep "gservice" | wc -l` 79 | echo -e "\nNumber of service accounts in members.csv = $MEMBER_COUNT" 80 | TOTAL_JSONS_NOW=`ls $KEYS_DIR | grep ".json" | wc -l` 81 | let TOTAL_JSONS_MADE=$TOTAL_JSONS_NOW-$TOTAL_JSONS_BEF 82 | echo -e "Total SA json keys created for project $PROJECT = $TOTAL_JSONS_MADE" 83 | let COUNT=$COUNT+$NUM_SAS_PER_PROJECT 84 | } 85 | 86 | main() { 87 | mkdir -p $KEYS_DIR 88 | [ -f $KEYS_DIR/members.csv ] && cat $KEYS_DIR/members.csv >> $KEYS_DIR/allmembers.csv && \ 89 | sort -uo $KEYS_DIR/allmembers.csv $KEYS_DIR/allmembers.csv 90 | echo "Group Email [Required],Member Email,Member Type,Member Role" >$KEYS_DIR/members.csv 91 | TOTAL_JSONS_START=`ls $KEYS_DIR | grep ".json" | wc -l` 92 | echo -e "\nTotal SA json keys before running sa-gen = $TOTAL_JSONS_START" 93 | for function in create_projects enable_apis create_sas create_keys ; do 94 | COUNT=$FIRST_SA_NUM 95 | for project_num in $(seq $FIRST_PROJECT_NUM $LAST_PROJECT_NUM); do 96 | eval $function 97 | sleep $SECTION_DELAY 98 | done 99 | done 100 | TOTAL_JSONS_END=`ls $KEYS_DIR | grep ".json" | wc -l` 101 | echo -e "\n\nTotal SA json keys BEFORE running sa-gen = $TOTAL_JSONS_START" 102 | echo -e "Total SA json keys AFTER running sa-gen = $TOTAL_JSONS_END" 103 | let TOTAL_JSONS_MADE=$TOTAL_JSONS_END-$TOTAL_JSONS_START 104 | echo -e "Total SA jsons CREATED = $TOTAL_JSONS_MADE" 105 | } 106 | 107 | main -------------------------------------------------------------------------------- /old/update-display-name: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Simple script to add / update the display name for your existing service accounts 3 | 4 | # Add a filter if you only want to include some projects e.g. "sacopy" for sacopy1, sacopy2 etc 5 | FILTER_PROJECTS="" 6 | # Add a unique identifier for user or account for tracking activity e.g. "user@domain" 7 | UNIQUE_ID="" 8 | 9 | proj_list=`gcloud projects list --sort-by=PROJECT_ID | grep "$FILTER_PROJECTS" | cut -d' ' -f1` 10 | 11 | for project in $proj_list;do 12 | gcloud config set project $project 13 | echo -e "Project name is $project \n" 14 | sa_list=`gcloud iam service-accounts list --format='value(email)' | sort` 15 | for sa in $sa_list;do 16 | sa_name="$UNIQUE_ID${sa%@*}" 17 | echo -e "Service Account is $sa" 18 | echo -e "Service Account Name is ${sa%@*}" 19 | gcloud iam service-accounts update $sa --display-name "$sa_name" 20 | done 21 | done -------------------------------------------------------------------------------- /sa-add2group: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will extract service account emails from json keys in a local folder, 3 | # then add the SA emails to a Google group. If the group does not exist it will create the group 4 | # Prerequisite: gcloud sdk 5 | 6 | # Get the service account keys location from command line argument or prompt user for input 7 | if [ -z "$1" ]; then 8 | read -p "Enter the location of the service account keys: " service_account_keys_location 9 | else 10 | service_account_keys_location="$1" 11 | fi 12 | 13 | # Get the google group email name from command line argument or prompt user for input 14 | if [ -z "$2" ]; then 15 | read -p "Enter the google group email to add the service account emails to: " google_group_email_name 16 | else 17 | google_group_email_name="$2" 18 | fi 19 | 20 | # Get the list of service account json keys 21 | service_account_keys=$(find "$service_account_keys_location" -type f -name "*.json" | sort | uniq ) 22 | 23 | # Extract the email addresses from the service account json keys 24 | email_addresses=() 25 | for service_account_key in $service_account_keys; do 26 | email_address=$(jq -r '.client_email' "$service_account_key") 27 | email_addresses+=("$email_address") 28 | done 29 | 30 | printf "There are %s unique service account emails.\n" "${#email_addresses[@]}" 31 | 32 | # Enable necessary Google APIs in gcloud sdk 33 | gcloud services enable admin.googleapis.com cloudresourcemanager.googleapis.com cloudidentity.googleapis.com 34 | 35 | # Check if the google group exists 36 | if gcloud identity groups describe "$google_group_email_name" &> /dev/null; then 37 | printf "The google group %s already exists.\n" "$google_group_email_name" 38 | else 39 | printf "The google group %s does not exist. Creating it.\n" "$google_group_email_name" 40 | organization_id=$(gcloud organizations list --format="value(ID)") 41 | if gcloud identity groups create "$google_group_email_name" --description="$google_group_email_name" --organization="$organization_id"; then 42 | printf "The google group %s was created successfully.\n" "$google_group_email_name" 43 | else 44 | printf "Failed to create the google group %s.\n" "$google_group_email_name" 45 | fi 46 | fi 47 | 48 | # Add service account emails to google group 49 | printf "Adding %s emails to %s\n" "${#email_addresses[@]}" "$google_group_email_name" 50 | for email in "${email_addresses[@]}"; do 51 | gcloud identity groups memberships add --group-email="$google_group_email_name" --member-email="$email" 52 | done -------------------------------------------------------------------------------- /sa-count: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This scipt will get a list of all projects in an account and print the 3 | # project name along with the number of service accounts per project 4 | 5 | PROJECTS=$(gcloud projects list --format="value(projectId)") 6 | 7 | # For each project, get the list of service accounts. 8 | for PROJECT in ${PROJECTS}; do 9 | 10 | # Get the list of service accounts in the project. 11 | SERVICE_ACCOUNTS=$(gcloud iam service-accounts list --project=${PROJECT}) 12 | 13 | # Count the number of service accounts. 14 | SERVICE_ACCOUNT_COUNT=$(grep -c "account" <<< ${SERVICE_ACCOUNTS}) 15 | 16 | # Print the project name and the number of service accounts. 17 | echo "${PROJECT}: ${SERVICE_ACCOUNT_COUNT}" 18 | 19 | done 20 | -------------------------------------------------------------------------------- /sa-delete: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will delete all service accounts in a project 3 | 4 | # List all projects and store them in an array 5 | PROJECTS=($(gcloud projects list --format="value(projectId)")) 6 | # Print the array with indices 7 | echo "Available projects:" 8 | for i in "${!PROJECTS[@]}" 9 | do 10 | echo "$i) ${PROJECTS[$i]}" 11 | done 12 | # Prompt the user to enter an index 13 | read -p "Enter the index of the project you want to delete all service accounts for: " INDEX 14 | # Validate the input 15 | if [[ $INDEX =~ ^[0-9]+$ ]] && [ $INDEX -ge 0 ] && [ $INDEX -lt ${#PROJECTS[@]} ] 16 | then 17 | # Get the project ID from the array 18 | PROJECT_ID=${PROJECTS[$INDEX]} 19 | # List all service accounts for the project and store them in an array 20 | SERVICE_ACCOUNTS=($(gcloud iam service-accounts list --project $PROJECT_ID --format="value(email)")) 21 | # Loop over the array and delete each service account 22 | for SA in "${SERVICE_ACCOUNTS[@]}" 23 | do 24 | echo "Deleting service account $SA" 25 | gcloud iam service-accounts delete $SA --quiet 26 | done 27 | else 28 | # Invalid input 29 | echo "Invalid index. Please try again." 30 | fi -------------------------------------------------------------------------------- /sa-emails: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will list all service account emails for json keys in a given directory 3 | 4 | # Get the path to the directory containing the JSON key files. 5 | if [ -z "$1" ]; then 6 | read -p "Enter the path to the directory containing the JSON key files: " key_file_dir 7 | else 8 | key_file_dir=$1 9 | fi 10 | 11 | # Check if the directory exists. 12 | if [ ! -d "$key_file_dir" ]; then 13 | echo "The directory '$key_file_dir' does not exist." 14 | exit 1 15 | fi 16 | 17 | # Iterate over all the JSON key files in the directory. 18 | for key_file in "$key_file_dir"/*.json; do 19 | service_account_emails=$(jq -r '.client_email' "$key_file") 20 | echo "$service_account_emails" 21 | done 22 | -------------------------------------------------------------------------------- /sa-gen: -------------------------------------------------------------------------------- 1 | #!/bin/bash -v 2 | 3 | function check_config() { 4 | if [ ! -f sa-gen.conf ]; then 5 | cp sa-gen-default.conf sa-gen.conf 6 | echo -e "\nCreated sa-gen.conf with default settings.\nEdit using nano or vim to specify a group name and email.\n" 7 | exit 8 | fi 9 | } 10 | 11 | # Display gcloud sdk organization and active admin project and enable admin APIs 12 | function check_prereqs() { 13 | gcloud organizations list 14 | ADMIN_PROJECT=`gcloud config get-value project` 15 | gcloud services enable --project "$ADMIN_PROJECT" drive.googleapis.com sheets.googleapis.com \ 16 | cloudidentity.googleapis.com admin.googleapis.com cloudresourcemanager.googleapis.com servicemanagement.googleapis.com 17 | read -p "Check the org and project. If wrong or blank then rerun gcloud init. Continue? y/n " yn 18 | if [[ $yn =~ ^[Nn]$ ]];then exit;fi 19 | } 20 | 21 | function create_projects() { 22 | for i in $(seq -f "%03g" "$FIRST_PROJECT_NUM" "$LAST_PROJECT_NUM"); do 23 | PROJECT_NAME="$PREFIX-$i" 24 | PROJECT_ID="$PROJECT_NAME-$SUFFIX" 25 | gcloud projects create "$PROJECT_ID" --name="$PROJECT_NAME" 26 | gcloud services enable --project "$PROJECT_ID" drive.googleapis.com sheets.googleapis.com 27 | done 28 | } 29 | 30 | function create_group() { 31 | ORG_ID=$(gcloud organizations list --format="value(ID)") 32 | gcloud identity groups create "$GROUP_EMAIL" --description="$GROUP_NAME" --organization="$ORG_ID" 33 | } 34 | 35 | function create_service_accounts() { 36 | JSON_COUNT=$((FJSON-1)) 37 | mkdir -p "$KEYS_DIR/all/" 38 | for i in $(seq -f "%03g" "$FIRST_PROJECT_NUM" "$LAST_PROJECT_NUM"); do 39 | PROJECT_NAME="$PREFIX-$i" 40 | PROJECT_ID="$PROJECT_NAME-$SUFFIX" 41 | for j in $(seq -f "%03g" 1 "$SAS_PER_PROJECT"); do 42 | SA_NAME="$PREFIX-$i-$j" 43 | EMAIL="$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" 44 | gcloud iam service-accounts create "$SA_NAME" --project="$PROJECT_ID" --display-name="$SA_NAME" 45 | gcloud identity groups memberships add --group-email="$GROUP_EMAIL" --member-email="$EMAIL" 46 | gcloud iam service-accounts keys create "$KEYS_DIR/$PROJECT_NAME/$((++JSON_COUNT)).json" --iam-account="$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --project="$PROJECT_ID" 47 | done 48 | cp "$KEYS_DIR/$PROJECT_NAME/"*.json "$KEYS_DIR/all/" 49 | done 50 | } 51 | 52 | function main() { 53 | check_config 54 | check_prereqs 55 | source sa-gen.conf 56 | create_projects 57 | create_group 58 | create_service_accounts 59 | } 60 | 61 | main 62 | -------------------------------------------------------------------------------- /sa-gen-default.conf: -------------------------------------------------------------------------------- 1 | # Copy or rename this file to sa-gen.conf and edit values as needed 2 | KEYS_DIR="/opt/sa" # path where you want to store sa JSON files 3 | FIRST_PROJECT_NUM=1 # First project number 4 | LAST_PROJECT_NUM=10 # Last project number 5 | SAS_PER_PROJECT=100 # Number of service accounts per project (max 100) 6 | FJSON=1 # First json file number when downloading 7 | PREFIX="sa" # Project prefix 8 | SUFFIX=`echo $RANDOM | md5sum | head -c 4` # Project suffix. Random 4 char alpha numeric 9 | # SUFFIX="" # Set this manually to use your own unique suffix 10 | GROUP_NAME="sa-group" # Display name for the group that contains all SA emails 11 | GROUP_EMAIL="sa-group@mydomain.com" # Full email name for group that contains SAs 12 | --------------------------------------------------------------------------------