Skip to content
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

infra/gcp: disable containerscanning and test-infra-trusted prow access for staging and release projects #2016

Merged
merged 9 commits into from
May 20, 2021
118 changes: 60 additions & 58 deletions infra/gcp/ensure-env-cip-auditor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,99 +39,91 @@ set -o pipefail
SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
. "${SCRIPT_DIR}/lib.sh"

SUBSCRIPTION_NAME="cip-auditor-invoker"
readonly CIP_AUDITOR_SUBSCRIPTION_NAME="cip-auditor-invoker"

readonly CIP_AUDITOR_SERVICES=(
# TODO: used directly, if so what for? if not, dependency of something else?
clouderrorreporting.googleapis.com
# TODO: used directly, if so what for? if not, dependency of something else?
cloudresourcemanager.googleapis.com
# The GCR auditor runs in Cloud Run
run.googleapis.com
# TODO: used directly, if so what for? if not, dependency of something else?
serviceusage.googleapis.com
# TODO: used directly, if so what for? if not, dependency of something else?
stackdriver.googleapis.com
)

# Get the auditor service's Cloud Run push endpoint (the HTTPS endpoint that the
# Pub/Sub subscription listening to the "gcr" topic can hit).
#
# $1: GCP project ID
function get_push_endpoint() {
if [ $# -lt 1 -o -z "$1" ]; then
echo "get_push_endpoint(project_id) requires 1 argument" >&2
if [ $# != 1 ] || [ -z "$1" ]; then
echo "${FUNCNAME[0]}(project) requires 1 argument" >&2
return 1
fi
local project_id="$1"
local project="${1}"

gcloud \
run services describe \
"${AUDITOR_SERVICE_NAME}" \
--platform=managed \
--format='value(status.url)' \
--project="${project_id}" \
--project="${project}" \
--region=us-central1
}

# This enables the necessary services to use Cloud Run.
#
# $1: GCP project ID
function enable_services() {
if [ $# -ne 1 -o -z "$1" ]; then
echo "enable_services(project_id) requires 1 argument" >&2
return 1
fi
local project_id="$1"

# Enable APIs.
local services=(
"serviceusage.googleapis.com"
"cloudresourcemanager.googleapis.com"
"stackdriver.googleapis.com"
"clouderrorreporting.googleapis.com"
"run.googleapis.com"
)
echo "Enabling services"
for service in "${services[@]}"; do
gcloud --project="${project_id}" services enable "${service}"
done
}

# This sets up the GCP project so that it can be ready to deploy the cip-auditor
# service onto Cloud Run.
#
# $1: GCP project ID
# $2: GCP project number
function link_run_to_pubsub() {
if [ $# -lt 2 -o -z "$1" -o -z "$2" ]; then
echo "link_run_to_pubsub(project_id, project_number) requires 2 arguments" >&2
if [ $# != 2 ] || [ -z "$1" ] || [ -z "$2" ]; then
echo "${FUNCNAME[0]}(project, project_number) requires 2 arguments" >&2
return 1
fi
local project_id="$1"
local project="$1"
local project_number="$2"

local pubsub_serviceagent="service-${project_number}@gcp-sa-pubsub.iam.gserviceaccount.com"
local auditor_invoker_sa
auditor_invoker_sa=$(svc_acct_email "${project}" "${AUDITOR_INVOKER_SVCACCT}")

# Create "gcr" topic if it doesn't exist yet.
if ! gcloud pubsub topics list --format='value(name)' --project="${project_id}" \
| grep "projects/${project_id}/topics/gcr"; then
if ! gcloud pubsub topics list --format='value(name)' --project="${project}" \
| grep "projects/${project}/topics/gcr"; then

gcloud pubsub topics create gcr --project="${project_id}"
gcloud pubsub topics create gcr --project="${project}"
fi

# Allow the Pub/Sub to create auth tokens in the project. This is part of
# the authentication bridge between the "gcr" Pub/Sub topic and the
# "--no-allow-unauthenticated" Cloud Run service option.
gcloud \
projects add-iam-policy-binding \
"${project_id}" \
--member="serviceAccount:service-${project_number}@gcp-sa-pubsub.iam.gserviceaccount.com" \
--role=roles/iam.serviceAccountTokenCreator
ensure_project_role_binding \
"${project}" \
"serviceAccount:${pubsub_serviceagent}" \
"roles/iam.serviceAccountTokenCreator"

# Create subscription if it doesn't exist yet.
if ! gcloud pubsub subscriptions list --format='value(name)' --project="${project_id}" \
| grep "projects/${project_id}/subscriptions/${SUBSCRIPTION_NAME}"; then
if ! gcloud pubsub subscriptions list --format='value(name)' --project="${project}" \
| grep "projects/${project}/subscriptions/${CIP_AUDITOR_SUBSCRIPTION_NAME}"; then

# Find HTTPS push endpoint (invocation endpoint) of the auditor. This
# URL will never change (part of the service name is baked into it), as
# per https://cloud.google.com/run/docs/deploying#url.
local auditor_endpoint
local auditor_endpoint=$(get_push_endpoint "${project_id}")
auditor_endpoint=$(get_push_endpoint "${project}")

gcloud \
pubsub subscriptions create \
"${SUBSCRIPTION_NAME}" \
"${CIP_AUDITOR_SUBSCRIPTION_NAME}" \
--topic=gcr \
--expiration-period=never \
--push-auth-service-account="$(svc_acct_email "${project_id}" "${AUDITOR_INVOKER_SVCACCT}")" \
--push-auth-service-account="${auditor_invoker_sa}"\
--push-endpoint="${auditor_endpoint}" \
--project="${project_id}"
--project="${project}"
fi
}

Expand All @@ -140,30 +132,40 @@ function link_run_to_pubsub() {
# create a Cloud Run endpoint (https:// URL) that can be used in the rest of
# this script (as auditor_endpoint).
function create_dummy_endpoint() {
local CLOUD_RUN_SERVICE_ACCOUNT="$(svc_acct_email "${PROJECT_ID}" "${AUDITOR_SVCACCT}")"
if [ $# != 1 ] || [ -z "$1" ]; then
echo "${FUNCNAME[0]}(project) requires 1 argument" >&2
return 1
fi
local project="${1}"

local serviceaccount
serviceaccount="$(svc_acct_email "${project}" "${AUDITOR_SVCACCT}")"

gcloud run deploy "${AUDITOR_SERVICE_NAME}" \
--image="gcr.io/cloudrun/hello" \
--platform=managed \
--no-allow-unauthenticated \
--region=us-central1 \
--project="${PROJECT_ID}" \
--service-account="${CLOUD_RUN_SERVICE_ACCOUNT}"
--project="${project}" \
--service-account="${serviceaccount}"
}

function main() {
# We want to run in the artifacts project to get pubsub most easily.
local PROJECT_ID="k8s-artifacts-prod"
local PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format "value(projectNumber)")
function ensure_cip_auditor_env() {
local project="${1}"
local project_number
project_number=$(gcloud projects describe "${project}" --format "value(projectNumber)")

enable_services "${PROJECT_ID}"
echo "Enabling services"
ensure_services "${project}" "${CIP_AUDITOR_SERVICES[@]}" 2>&1 | indent

if ! get_push_endpoint "${PROJECT_ID}"; then
if ! get_push_endpoint "${project}"; then
echo >&2 "Could not determine push endpoint for the auditor's Cloud Run service."
echo >&2 "Deploying a dummy image instead to create the Cloud Run endpoint."
create_dummy_endpoint
create_dummy_endpoint "${project}"
fi

link_run_to_pubsub "${PROJECT_ID}" "${PROJECT_NUMBER}"
link_run_to_pubsub "${project}" "${project_number}"
}

main "$@"
# We want to run in the artifacts project to get pubsub most easily.
ensure_cip_auditor_env "k8s-artifacts-prod"
2 changes: 1 addition & 1 deletion infra/gcp/ensure-prod-storage-gclb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ color 6 "Ensuring project exists: ${PROD_PROJECT}"
ensure_project "${PROD_PROJECT}"

color 6 "Enabling the compute API: ${PROD_PROJECT}"
enable_api "${PROD_PROJECT}" compute.googleapis.com
ensure_services "${PROD_PROJECT}" compute.googleapis.com

color 6 "Reconciling Global Address"
ensure_global_address "${PROD_PROJECT}" "${NAME}" "IP Address for GCLB for binary artifacts"
Expand Down
41 changes: 19 additions & 22 deletions infra/gcp/ensure-prod-storage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@ GCR_AUDIT_TEST_PROD_PROJECT="k8s-gcr-audit-test-prod"
RELEASE_TESTPROD_PROJECT="k8s-release-test-prod"
RELEASE_STAGING_CLOUDBUILD_ACCOUNT="615281671549@cloudbuild.gserviceaccount.com"

PROW_UNTRUSTED_BUILD_CLUSTER_PROJECTS=(
"k8s-prow-builds"
"k8s-infra-prow-build"
)

PROW_TRUSTED_BUILD_CLUSTER_PROJECTS=(
"k8s-prow"
"k8s-infra-prow-build-trusted"
)

# This is a list of all prod projects. Each project will be configured
# similarly, with a GCR repository and a GCS bucket of the same name.
#
Expand All @@ -92,6 +82,20 @@ ALL_PROD_BUCKETS=(
"kind"
)

readonly PROD_PROJECT_SERVICES=(
# prod projects may perform container analysis
containeranalysis.googleapis.com
# prod projects host containers in GCR
containerregistry.googleapis.com
# prod projects host binaries in GCS
storage-component.googleapis.com
)

readonly PROD_PROJECT_DISABLED_SERVICES=(
# Disabling per https://github.com/kubernetes/k8s.io/issues/1963
containerscanning.googleapis.com
)

# Regions for prod GCR.
PROD_REGIONS=(us eu asia)

Expand Down Expand Up @@ -192,18 +196,15 @@ function ensure_all_prod_projects() {
color 6 "Ensuring project exists: ${prj}"
ensure_project "${prj}"

color 6 "Enabling the container registry API: ${prj}"
enable_api "${prj}" containerregistry.googleapis.com
color 6 "Ensuring Services to host and analyze aritfacts: ${prj}"
ensure_services "${prj}" "${PROD_PROJECT_SERVICES[@]}" 2>&1 | indent

color 6 "Enabling the container analysis API: ${prj}"
enable_api "${prj}" containeranalysis.googleapis.com
color 6 "Ensuring disabled services for prod project: ${prj}"
ensure_disabled_services "${prj}" "${PROD_PROJECT_DISABLED_SERVICES[@]}" 2>&1 | indent

color 6 "Ensuring the GCR repository: ${prj}"
ensure_prod_gcr "${prj}" 2>&1 | indent

color 6 "Enabling the GCS API: ${prj}"
enable_api "${prj}" storage-component.googleapis.com

color 6 "Ensuring the GCS bucket: gs://${prj}"
ensure_prod_gcs_bucket "${prj}" "gs://${prj}" 2>&1 | indent
done
Expand Down Expand Up @@ -234,10 +235,6 @@ function ensure_all_prod_special_cases() {
"gs://${PROD_PROJECT}" \
"${SCRIPT_DIR}/static/prod-storage"

# Special case: enable vulnerability scanning on the prod GCR.
color 6 "Enabling GCR vulnerability scanning in the prod GCR"
enable_api "${PROD_PROJECT}" containerscanning.googleapis.com

# Special case: enable people to read vulnerability reports.
color 6 "Empowering artifact-security group to real vulnerability reports"
SEC_GROUP="k8s-infra-artifact-security@kubernetes.io"
Expand Down Expand Up @@ -397,4 +394,4 @@ function main() {
color 6 "Done"
}

main
main
39 changes: 24 additions & 15 deletions infra/gcp/ensure-release-projects.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ if [ $# = 0 ]; then
set -- "${PROJECTS[@]}"
fi

ADMINS="k8s-infra-release-admins@kubernetes.io"
WRITERS="k8s-infra-release-editors@kubernetes.io"
VIEWERS="k8s-infra-release-viewers@kubernetes.io"

readonly RELEASE_PROJECT_SERVICES=(
cloudbuild.googleapis.com
cloudkms.googleapis.com
Expand All @@ -56,6 +52,12 @@ readonly RELEASE_PROJECT_SERVICES=(
)

for PROJECT; do

if ! (printf '%s\n' "${PROJECTS[@]}" | grep -q "^${PROJECT}$"); then
color 2 "Skipping unrecognized release project name: ${PROJECT}"
continue
fi

color 3 "Configuring: ${PROJECT}"

# The names of the buckets
Expand All @@ -67,7 +69,7 @@ for PROJECT; do
color 6 "Ensuring project exists: ${PROJECT}"
ensure_project "${PROJECT}"

for group in ${ADMINS} ${WRITERS} ${VIEWERS}; do
for group in ${RELEASE_ADMINS} ${RELEASE_MANAGERS} ${RELEASE_VIEWERS}; do
# Enable admins to use the UI
color 6 "Empowering ${group} as project viewers"
empower_group_as_viewer "${PROJECT}" "${group}"
Expand All @@ -88,7 +90,7 @@ for PROJECT; do
empower_gcr_admins "${PROJECT}"

# Enable GCR writers
for group in ${ADMINS} ${WRITERS}; do
for group in ${RELEASE_ADMINS} ${RELEASE_MANAGERS}; do
color 6 "Empowering ${group} to GCR"
empower_group_to_write_gcr "${group}" "${PROJECT}"
done
Expand All @@ -107,7 +109,7 @@ for PROJECT; do
empower_gcs_admins "${PROJECT}" "${BUCKET}"

# Enable writers on the bucket
for group in ${ADMINS} ${WRITERS}; do
for group in ${RELEASE_ADMINS} ${RELEASE_MANAGERS}; do
color 6 "Empowering ${group} to GCS"
empower_group_to_write_gcs_bucket "${group}" "${BUCKET}"
done
Expand All @@ -116,18 +118,26 @@ for PROJECT; do
# Enable GCB and Prow to build and push images.

# Let project writers use GCB.
for group in ${ADMINS} ${WRITERS}; do
for group in ${RELEASE_ADMINS} ${RELEASE_MANAGERS}; do
color 6 "Empowering ${group} as GCB editors"
empower_group_for_gcb "${PROJECT}" "${group}"
done

# Let prow trigger builds and access the scratch bucket
color 6 "Empowering Prow"
empower_prow "${PROJECT}" "${GCB_BUCKET}"
serviceaccount="${GCB_BUILDER_SVCACCT}"
principal="serviceAccount:${serviceaccount}"

color 6 "Ensuring ${serviceaccount} can use GCB in project: ${PROJECT}"
ensure_project_role_binding "${PROJECT}" "${principal}" "roles/cloudbuild.builds.builder"
ensure_gcs_role_binding "${GCB_BUCKET}" "${principal}" "objectCreator"
ensure_gcs_role_binding "${GCB_BUCKET}" "${principal}" "objectViewer"

color 6 "Ensuring k8s-prow / test-infra-trusted can no longer use GCB in project: ${PROJECT}"
ensure_removed_google_prow_bindings "${PROJECT}" "${GCB_BUCKET}"
Comment on lines +135 to +136
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure but this part is applied once. Why do it ever time the script is used ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to remove this in a follow-up PR. I was starting to get lazy by this point so I didn't go as far as making a "bindings to remove" array like I did in ensure-organizations.


# Let project admins use KMS.
color 6 "Empowering ${ADMINS} as KMS admins"
empower_group_for_kms "${PROJECT}" "${ADMINS}"
color 6 "Empowering ${RELEASE_ADMINS} as KMS admins"
empower_group_for_kms "${PROJECT}" "${RELEASE_ADMINS}"

color 6 "Done"
done
Expand All @@ -141,7 +151,6 @@ RELEASE_BUCKETS=(
"gs://k8s-release-dev-eu"
"gs://k8s-release-pull"
)
PROW_BUILD_SVCACCT=$(svc_acct_email "k8s-infra-prow-build" "prow-build")

for BUCKET in "${RELEASE_BUCKETS[@]}"; do
color 3 "Configuring bucket: ${BUCKET}"
Expand All @@ -155,10 +164,10 @@ for BUCKET in "${RELEASE_BUCKETS[@]}"; do
empower_gcs_admins "k8s-release" "${BUCKET}"

# Enable prow to write to the bucket
empower_svcacct_to_write_gcs_bucket "${PROW_BUILD_SVCACCT}" "${BUCKET}"
empower_svcacct_to_write_gcs_bucket "${PROW_BUILD_SERVICE_ACCOUNT}" "${BUCKET}"

# Enable writers on the bucket
for group in ${ADMINS} ${WRITERS}; do
for group in ${RELEASE_ADMINS} ${RELEASE_MANAGERS}; do
color 6 "Empowering ${group} to GCS"
empower_group_to_write_gcs_bucket "${group}" "${BUCKET}"
done
Expand Down
Loading