-
Notifications
You must be signed in to change notification settings - Fork 0
/
collect-bucket-permissions.sh
executable file
·122 lines (98 loc) · 3.22 KB
/
collect-bucket-permissions.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env bash
#
# Lists all buckets in your GCP project and their iam bindings
#
set -e
USAGE="USAGE:
collect-bucket-permissions [OPTIONS]
Options:
-p, --project project_id Use the specified project instead of your gcloud default
-o, --output format Change output format. Can be one of 'yaml', 'spaced', 'spaced-40', 'spaced-80' and 'spaced-120'
--sa-project For service accounts also print the project which contains it (given the permissions)
Note: You need to be logged into gcloud (gcloud auth login) when executing this command!"
. "$(dirname "$BASH_SOURCE")/lib/parse_args.sh"
declare -a KEYWORDS=("-p" "--project" "-o" "--output" "--sa-project")
set_trap 1 2
parse_args __USAGE "$USAGE" "$@"
spaced_format='{ printf "%s%-SPACE_WIDTHs %s\n", " - ", $1, $2 }'
yaml_format='{ printf "%s\n%s%s\"\n%s\"%s\n", " -", " member: ", $1, " role: ", $2 }'
yaml_format_with_pid='{ printf "%s\n%s%s\"\n%s\"%s\n%s\"%s\"\n", " -", " member: ", $1, " role: ", $2, " project: ", $3 }'
format='{ print " - ", $1, $2 }'
show_sa_projects=0
if [[ " ${ARGS[*]} " =~ .*"--sa-project".* ]]
then
show_sa_projects=1
fi
project_arg=""
if [[ -n "${KW_ARGS["-p"-""]}" ]] || [[ -n "${KW_ARGS["--project"]}" ]]
then
project_arg="${KW_ARGS["-p"]}"
project_arg="-p ${KW_ARGS["--project"]-"$project_arg"}"
fi
format_name="${KW_ARGS["-o"]-"default"}"
format_name="${KW_ARGS["--output"]-"$format_name"}"
if [[ "$format_name" != "default" ]]
then
if [[ $format_name == "yaml" ]]
then
format="$yaml_format"
elif [[ $format_name == "spaced" ]] || [[ $format_name == "spaced-40" ]]
then
format="$( echo "$spaced_format" | sed 's/SPACE_WIDTH/39/' )"
elif [[ $format_name == "spaced-80" ]]
then
format="$( echo "$spaced_format" | sed 's/SPACE_WIDTH/79/' )"
elif [[ $format_name == "spaced-120" ]]
then
format="$( echo "$spaced_format" | sed 's/SPACE_WIDTH/119/' )"
else
echo "ERROR: Invalid output format '$format_name'!"
exit 1
fi
fi
if [[ $show_sa_projects == 1 ]]
then
if [[ "$yaml_format" == "$format" ]]
then
format="$yaml_format_with_pid"
else
echo "ERROR: --sa-project is only supported for yaml output"
exit 1
fi
fi
find_sa_project() {
if [[ "$1" =~ .*serviceAccount:.* ]]
then
sa_mail=${1##*serviceAccount:}
sa_mail=${sa_mail%\"}
#>&2 echo $1
#>&2 echo $sa_mail
project="$(gcloud iam service-accounts describe "$sa_mail" 2> /dev/null | grep projectId || echo "unknown")"
echo ${project##*projectId:}
else
echo "none"
fi
}
for bucket in $(gsutil ls $project_arg)
do
bucket_iam="$(gsutil iam get $bucket)"
echo "$(basename $bucket):"
bindings="$(
echo "$bucket_iam" \
| jq '.bindings[] | "\(.members[]) \(.role)"'
)"
if [[ $show_sa_projects == 1 ]]
then
bindings_old="$bindings"
bindings=""
while IFS= read -r line
do
account="$(echo $line | awk '{print $1}')"
bindings="${bindings}${line} $(find_sa_project "$account")
"
done < <(printf '%s\n' "$bindings_old")
bindings="${bindings%'
'}"
fi
echo "$bindings" | awk "$format"
done