Skip to content

Commit

Permalink
bin/podman-cloud: add a container to access Kubernetes, GCloud and AWS
Browse files Browse the repository at this point in the history
  • Loading branch information
fishilico committed Apr 14, 2024
1 parent 873a5bc commit 34e1544
Show file tree
Hide file tree
Showing 3 changed files with 323 additions and 0 deletions.
319 changes: 319 additions & 0 deletions bin/podman-cloud
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2024 Nicolas Iooss
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Run various cloud-related tools in a container
#
# - Kubectl from https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
# - to view the configuration: kubectl config view
# - to get current cluster-wide permissions: kubectl auth can-i --list
# - to list namespaces: kubectl get ns
#
# - AWS (Amazon Web Service) CLI from
# https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#cliv2-linux-install
# - to get active user: aws sts get-caller-identity
# - to authenticate with a MFA (Multi-Factor Authentication) token:
# export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
# aws sts get-session-token --serial-number "arn:aws:iam::$AWS_ACCOUNT_ID:mfa/$AWS_USER" --token-code 112233
# - to list files in an AWS S3 bucket: aws s3 ls s3://bucket
# - to get IAM policy: aws iam get-account-authorization-details
# - to list Compute instances: aws ec2 describe-instances
#
# - Google Cloud CLI from https://cloud.google.com/sdk/docs/install#deb
# This provides gcloud and gsutil.
# - to list active sessions: gcloud auth list
# - to authenticate with service credentials in a JSON file:
# gcloud auth login --no-browser --cred-file google-workspace-credentials.json
# gcloud config set account ...
# - to list files in a Google Storage: gsutil ls gs://bucket
# - to list projects: gcloud projects list
# - to get IAM policy for a project: gcloud projects get-iam-policy $PROJECT_ID
# - to list Compute instances: gcloud compute instances list
# - to get SSH config: gcloud compute config-ssh

set -e

build_container() {
# Update the base image
mapfile -t OLD_BASE_IMAGES < <(podman image list '--format={{.Id}}' docker.io/library/debian:bookworm-slim)
podman pull docker.io/library/debian:bookworm-slim
for OLD_BASE_IMAGE in "${OLD_BASE_IMAGES[@]}" ; do
if [ "$(podman image list '--format={{.Dangling}}' --filter "id=${OLD_BASE_IMAGE}")" = 'true' ] ; then
echo "Removing old podman base image ${OLD_BASE_IMAGE}"
podman image rm -- "${OLD_BASE_IMAGE}"
fi
done

# Build a container with cloud-related tools
podman build --no-cache -t localhost/podman-cloud -f /dev/stdin << EOF
FROM docker.io/library/debian:bookworm-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install --no-install-recommends --no-install-suggests -y \
ca-certificates \
curl \
gnupg \
jq \
less \
mandoc \
openssh-client \
python3 \
python-is-python3 \
unzip \
vim && \
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' > /etc/apt/sources.list.d/kubernetes.list && \
echo 'Package: kubectl' > /etc/apt/preferences.d/k8s && \
echo 'Pin: release o=obs://build.opensuse.org/isv:kubernetes:core:stable:v1.29/deb,n=deb,l=isv:kubernetes:core:stable:v1.29,c=' >> /etc/apt/preferences.d/k8s && \
echo 'Pin-Priority: 1000' >> /etc/apt/preferences.d/k8s && \
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/cloud.google.gpg && \
echo 'deb [signed-by=/etc/apt/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main' > /etc/apt/sources.list.d/google-cloud-sdk.list && \
apt-get update && \
apt-get install --no-install-recommends --no-install-suggests -y google-cloud-cli google-cloud-cli-gke-gcloud-auth-plugin kubectl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/ /var/log/* && \
cd /opt && \
curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip && \
unzip -q awscliv2.zip && \
./aws/install --bin-dir /usr/bin && \
rm -r awscliv2.zip aws
EOF
}

# Option --update updates the container if it already exists
if [ $# -ge 1 ] && [ "$1" = '--update' ] ; then
shift
mapfile -t OLD_IMAGES < <(podman image list '--format={{.Id}}' localhost/podman-cloud)
build_container
for OLD_IMAGE in "${OLD_IMAGES[@]}" ; do
if [ "$(podman image list '--format={{.Dangling}}' --filter "id=${OLD_IMAGE}")" = 'true' ] ; then
echo "Removing old podman image ${OLD_IMAGE}"
podman image rm -- "${OLD_IMAGE}"
fi
done
elif ! podman image exists localhost/podman-cloud ; then
build_container
fi

# Option --no-start can be used to build the container without starting it
if [ $# -ge 1 ] && [ "$1" = '--no-start' ] ; then
exit
fi

PODMAN_ARGS=()

# Share files provided by environment variables
if [ -n "${AWS_CA_BUNDLE:-}" ]; then
PODMAN_ARGS+=(-v "${AWS_CA_BUNDLE}:${AWS_CA_BUNDLE}")
fi
if [ -n "${AWS_CONFIG_FILE:-}" ]; then
PODMAN_ARGS+=(-v "${AWS_CONFIG_FILE}:${AWS_CONFIG_FILE}")
fi
if [ -n "${AWS_WEB_IDENTITY_TOKEN_FILE:-}" ]; then
PODMAN_ARGS+=(-v "${AWS_WEB_IDENTITY_TOKEN_FILE}:${AWS_WEB_IDENTITY_TOKEN_FILE}")
fi
if [ -n "${KUBECONFIG:-}" ]; then
PODMAN_ARGS+=(-v "${KUBECONFIG}:${KUBECONFIG}")
fi

while [ $# -ge 1 ] ; do
case "$1" in
-v|--volume)
if [ $# -lt 2 ] ; then
break
fi
# Configure a shared volume
PODMAN_ARGS+=(-v "$2")
shift 2
;;
*)
# Propagate the command line to the subcommand
break
;;
esac
done

# Use SCMP_ACT_LOG to record the denied syscalls
SECCOMP_PROFILE='
{
"defaultAction": "SCMP_ACT_ERRNO",
"syscalls": [
{
"names": [
"access",
"arch_prctl",
"bind",
"brk",
"capset",
"chdir",
"chmod",
"chown",
"clone",
"clone3",
"close",
"connect",
"dup",
"dup2",
"dup3",
"epoll_create",
"epoll_create1",
"epoll_ctl",
"epoll_pwait",
"execve",
"exit",
"exit_group",
"faccessat2",
"fadvise64",
"fchdir",
"fchmod",
"fchmodat",
"fchown",
"fchownat",
"fcntl",
"fdatasync",
"flock",
"fstat",
"fstatfs",
"fsync",
"ftruncate",
"futex",
"getcwd",
"getdents64",
"getegid",
"geteuid",
"getgid",
"getgroups",
"getpeername",
"getpgrp",
"getpid",
"getppid",
"getrandom",
"getresgid",
"getresuid",
"getrlimit",
"getsockname",
"getsockopt",
"gettid",
"getuid",
"ioctl",
"kill",
"lchown",
"lgetxattr",
"link",
"lseek",
"lstat",
"madvise",
"mkdir",
"mkdirat",
"mmap",
"mprotect",
"mremap",
"munmap",
"nanosleep",
"newfstatat",
"openat",
"pipe2",
"poll",
"prctl",
"pread64",
"prlimit64",
"pselect6",
"pwrite64",
"read",
"readlink",
"readlinkat",
"recvfrom",
"recvmsg",
"rename",
"renameat",
"rmdir",
"rseq",
"rt_sigaction",
"rt_sigprocmask",
"rt_sigreturn",
"sched_getaffinity",
"sched_yield",
"sendmmsg",
"sendmsg",
"sendto",
"set_robust_list",
"set_tid_address",
"setgroups",
"setpgid",
"setresgid",
"setresuid",
"setsid",
"setsockopt",
"sigaltstack",
"socket",
"stat",
"statfs",
"statx",
"symlink",
"sync_file_range",
"sysinfo",
"tgkill",
"umask",
"uname",
"unlink",
"unlinkat",
"utimensat",
"vfork",
"wait4",
"waitid",
"write",
"writev"
],
"action": "SCMP_ACT_ALLOW"
}
]
}'

# Propage authentication variables from the environment too
# - AWS: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
exec podman run --rm \
--env AWS_ACCESS_KEY_ID \
--env AWS_CA_BUNDLE \
--env AWS_CONFIG_FILE \
--env AWS_CLI_AUTO_PROMPT \
--env AWS_CLI_FILE_ENCODING \
--env AWS_DEFAULT_OUTPUT \
--env AWS_DEFAULT_REGION \
--env "AWS_EC2_METADATA_DISABLED=${AWS_EC2_METADATA_DISABLED:-true}" \
--env AWS_ENDPOINT_URL \
--env AWS_IGNORE_CONFIGURED_ENDPOINT_URLS \
--env AWS_MAX_ATTEMPTS \
--env AWS_PAGER \
--env AWS_PROFILE \
--env AWS_REGION \
--env AWS_RETRY_MODE \
--env AWS_ROLE_ARN \
--env AWS_ROLE_SESSION_NAME \
--env AWS_SECRET_ACCESS_KEY \
--env AWS_SESSION_TOKEN \
--env AWS_USE_DUALSTACK_ENDPOINT \
--env AWS_USE_FIPS_ENDPOINT \
--env AWS_WEB_IDENTITY_TOKEN_FILE \
--env KUBECONFIG \
"${PODMAN_ARGS[@]}" \
--security-opt seccomp=<(printf %s "$SECCOMP_PROFILE") \
-ti localhost/podman-cloud "$@"
3 changes: 3 additions & 0 deletions specific/update_podman_containers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ set -eux
if podman image exists localhost/podman-bpytop ; then
"${HOME_FILES_BIN}/podman-bpytop" --update --no-start
fi
if podman image exists localhost/podman-cloud ; then
"${HOME_FILES_BIN}/podman-cloud" --update aws --version
fi
if podman image exists localhost/podman-codespell ; then
"${HOME_FILES_BIN}/podman-codespell" --update /dev/null
fi
Expand Down
1 change: 1 addition & 0 deletions tests/run_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
'ping6-local': 'args[-h]',
'ping-box': 'never',
'podman-bpytop': 'never',
'podman-cloud': 'never',
'podman-codespell': 'never',
'podman-ghidra': 'never',
'podman-impacket-smbserver': 'never',
Expand Down

0 comments on commit 34e1544

Please sign in to comment.