-
Notifications
You must be signed in to change notification settings - Fork 822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
audit-followup: remove stale iam bindings for e2e projects #1722
Merged
k8s-ci-robot
merged 2 commits into
kubernetes:main
from
spiffxp:reconcile-prow-viewer-iam
Feb 25, 2021
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Copyright 2021 The Kubernetes Authors. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# IAM utility functions | ||
# | ||
# This is intended to be very general-purpose and "low-level". Higher-level | ||
# policy does not belong here. | ||
# | ||
# This MUST NOT be used directly. Source it via lib.sh instead. | ||
|
||
# Ensure that custom IAM role exists, creating one if needed | ||
# Arguments: | ||
# $1: The GCP project | ||
# $2: The role name (e.g. "ServiceAccountLister") | ||
# $3: The role title (e.g. "Service Account Lister") | ||
# $4: The role description (e.g. "Can list ServiceAccounts.") | ||
# $5+: The role permissions (e.g. "iam.serviceAccounts.list") | ||
# Example usage: | ||
# ensure_custom_iam_role \ | ||
# kubernetes-public \ | ||
# ServiceAccountLister \ | ||
# "Service Account Lister" \ | ||
# "Can list ServiceAccounts." \ | ||
# iam.serviceAccounts.list | ||
function ensure_custom_iam_role() { | ||
if [ $# -lt 5 ] || [ -z "${1}" ] || [ -z "${2}" ] || [ -z "${3}" ] \ | ||
|| [ -z "${4}" ] || [ -z "${5}" ] | ||
then | ||
echo -n "ensure_custom_iam_role(gcp_project, name, title," >&2 | ||
echo " description, permission...) requires at least 5 arguments" >&2 | ||
return 1 | ||
fi | ||
|
||
local gcp_project="${1}"; shift | ||
local name="${1}"; shift | ||
local title="${1}"; shift | ||
local description="${1}"; shift | ||
local permissions; permissions=$(join_by , "$@") | ||
|
||
if ! gcloud --project "${gcp_project}" iam roles describe "${name}" \ | ||
>/dev/null 2>&1 | ||
then | ||
gcloud --project "${gcp_project}" --quiet \ | ||
iam roles create "${name}" \ | ||
--title "${title}" \ | ||
--description "${description}" \ | ||
--stage GA \ | ||
--permissions "${permissions}" | ||
fi | ||
} | ||
|
||
# Ensure that custom IAM role exists and is in sync with definition in file | ||
# Arguments: | ||
# $1: The scope of the role (e.g. "org", "project:foobar") | ||
# $2: The role name (e.g. "prow.viewer") | ||
# $3: The file (e.g. "/path/to/file.yaml") | ||
function ensure_custom_iam_role_from_file() { | ||
if [ ! $# -eq 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then | ||
echo "ensure_custom_iam_role_from_file(scope, name, file) requires 3 arguments" >&2 | ||
return 1 | ||
fi | ||
|
||
local scope="${1}" | ||
local name="${2}" | ||
local file="${3}" | ||
|
||
scope_flag="" | ||
if [[ "${scope}" == "org" ]]; then | ||
scope_flag="--organization ${GCP_ORG}" | ||
elif [[ "${scope}" =~ "^project:" ]]; then | ||
scope_flag="--project $(echo ${scope} | cut -d: -f2-)" | ||
else | ||
echo "ensure_custom_iam_role_from_file(scope, name, file) scope must be one of 'org' or 'project:project-id'" >&2 | ||
return 1 | ||
fi | ||
|
||
if ! gcloud iam roles describe ${scope_flag} "${name}" \ | ||
>/dev/null 2>&1 | ||
then | ||
# be noisy when creating a role | ||
gcloud iam roles create ${scope_flag} "${name}" --file "${file}" | ||
else | ||
# be quiet when updating, only output name of role | ||
gcloud iam roles update ${scope_flag} "${name}" --file "${file}" | grep ^name: | ||
fi | ||
} | ||
|
||
# Return the full name of a custom IAM role defined at the org level | ||
# Arguments: | ||
# $1: The role name (e.g. "prow.viewer") | ||
function custom_org_role_name() { | ||
if [ ! $# -eq 1 -o -z "$1" ]; then | ||
echo "custom_org_role_name(name) requires 1 arguments" >&2 | ||
return 1 | ||
fi | ||
|
||
local name="${1}" | ||
|
||
echo "organizations/${GCP_ORG}/roles/${name}" | ||
} | ||
|
||
# Ensure that IAM binding exists at org level | ||
# Arguments: | ||
# $1: The role name (e.g. "prow.viewer") | ||
# $2: The file (e.g. "/path/to/file.yaml") | ||
function ensure_org_role_binding() { | ||
if [ ! $# -eq 2 -o -z "$1" -o -z "$2" ]; then | ||
echo "ensure_org_role_binding(principal, role) requires 2 arguments" >&2 | ||
return 1 | ||
fi | ||
|
||
local org="${GCP_ORG}" | ||
local principal="${1}" | ||
local role="${2}" | ||
|
||
gcloud \ | ||
organizations add-iam-policy-binding "${GCP_ORG}" \ | ||
--member "${principal}" \ | ||
--role "${role}" | ||
} | ||
|
||
# Ensure that IAM binding exists at project level | ||
# Arguments: | ||
# $1: The project id (e.g. "k8s-infra-foo") | ||
# $2: The principal (e.g. "group:[email protected]") | ||
# $3: The role name (e.g. "roles/storage.objectAdmin") | ||
function ensure_project_role_binding() { | ||
if [ ! $# -eq 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then | ||
echo "ensure_project_role_binding(project, principal, role) requires 3 arguments" >&2 | ||
return 1 | ||
fi | ||
|
||
local project="${1}" | ||
local principal="${2}" | ||
local role="${3}" | ||
|
||
gcloud \ | ||
projects add-iam-policy-binding "${project}" \ | ||
--member "${principal}" \ | ||
--role "${role}" | ||
} | ||
|
||
# Ensure that IAM binding has been removed at project level | ||
# Arguments: | ||
# $1: The project id (e.g. "k8s-infra-foo") | ||
# $2: The principal (e.g. "group:[email protected]") | ||
# $3: The role name (e.g. "roles/foo.bar") | ||
function ensure_removed_project_role_binding() { | ||
if [ ! $# -eq 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then | ||
echo "ensure_removed_project_role_binding(project, principal, role) requires 3 arguments" >&2 | ||
return 1 | ||
fi | ||
local project="${1}" | ||
local principal="${2}" | ||
local role="${3}" | ||
|
||
_ensure_removed_resource_role_binding "projects" "${project}" "${principal}" "${role}" | ||
} | ||
|
||
# Ensure that IAM binding has been removed at resource level | ||
# Arguments: | ||
# $1: The resource type (e.g. "projects", "organizations", "secrets" ) | ||
# $2: The id of the resource (e.g. "k8s-infra-foo", "12345") | ||
# $3: The principal (e.g. "group:[email protected]") | ||
# $4: The role name (e.g. "roles/foo.bar") | ||
function _ensure_removed_resource_role_binding() { | ||
if [ ! $# -eq 4 -o -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" ]; then | ||
echo "ensure_removed_project_role_binding(resource, id, principal, role) requires 4 arguments" >&2 | ||
return 1 | ||
fi | ||
|
||
local resource="${1}" | ||
local id="${2}" | ||
local principal="${3}" | ||
local role="${4}" | ||
|
||
# gcloud remove-iam-policy-binding errors if binding doesn't exist, so confirm it does | ||
if gcloud "${resource}" get-iam-policy "${id}" \ | ||
--flatten="bindings[].members" \ | ||
--format='value(bindings.role)' \ | ||
--filter="bindings.members='${principal}' AND bindings.role='${role}'" | grep -q "${role}"; then | ||
gcloud \ | ||
"${resource}" remove-iam-policy-binding "${id}" \ | ||
--member "${principal}" \ | ||
--role "${role}" | ||
fi | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ set -o nounset | |
set -o pipefail | ||
|
||
SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}") | ||
. "${SCRIPT_DIR}/lib.sh" | ||
. "${SCRIPT_DIR}/../lib.sh" | ||
|
||
function usage() { | ||
echo "usage: $0 [repo...]" > /dev/stderr | ||
|
@@ -111,6 +111,16 @@ for prj; do | |
( | ||
ensure_project "${prj}" | ||
|
||
color 6 "Ensure stale role bindings have been removed from e2e project: ${prj}" | ||
( | ||
# TODO(https://github.com/kubernetes/k8s.io/issues/1661): remove once verified as consistent | ||
color 6 "group:[email protected] should not have roles/viewer (ref: https://github.com/kubernetes/k8s.io/issues/1661)" | ||
ensure_removed_project_role_binding "${prj}" "group:[email protected]" "roles/viewer" | ||
# TODO(https://github.com/kubernetes/k8s.io/issues/299): remove once smarter logic folded into ensure_project | ||
color 6 "user:* should not have roles/owner for projects (ref: https://github.com/kubernetes/k8s.io/issues/299)" | ||
ensure_removed_project_role_binding "${prj}" "[email protected]" "roles/owner" | ||
) 2>&1 | indent | ||
|
||
color 6 "Enabling APIs necessary for kubernetes e2e jobs to use e2e project: ${prj}" | ||
enable_api "${prj}" compute.googleapis.com | ||
enable_api "${prj}" logging.googleapis.com | ||
|
@@ -143,7 +153,7 @@ for prj; do | |
--role roles/owner | ||
|
||
# NB: prow.viewer role is defined in ensure-organization.sh, that needs to have been run first | ||
color 6 "Empower [email protected] to view e2e project: ${prj}" | ||
color 6 "Empower [email protected] to view specific resources in e2e project: ${prj}" | ||
gcloud \ | ||
projects add-iam-policy-binding "${prj}" \ | ||
--member "group:[email protected]" \ | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixes regression introduced in #1636