Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ COPY --from=0 /go/src/github.com/k8snetworkplumbingwg/whereabouts/bin/whereabout
COPY --from=0 /go/src/github.com/k8snetworkplumbingwg/whereabouts/bin/ip-control-loop .
COPY --from=0 /go/src/github.com/k8snetworkplumbingwg/whereabouts/bin/node-slice-controller .
COPY script/install-cni.sh .
COPY script/lib.sh .
COPY script/token-watcher.sh .
CMD ["/install-cni.sh"]
2 changes: 2 additions & 0 deletions Dockerfile.arm64
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ LABEL org.opencontainers.image.source=https://github.com/k8snetworkplumbingwg/wh
COPY --from=0 /go/src/github.com/k8snetworkplumbingwg/whereabouts/bin/whereabouts .
COPY --from=0 /go/src/github.com/k8snetworkplumbingwg/whereabouts/bin/ip-control-loop .
COPY script/install-cni.sh .
COPY script/lib.sh .
COPY script/token-watcher.sh .
CMD ["/install-cni.sh"]
6 changes: 3 additions & 3 deletions Dockerfile.openshift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ COPY --from=builder /go/src/github.com/k8snetworkplumbingwg/whereabouts/bin/ip-c

LABEL org.opencontainers.image.source=https://github.com/k8snetworkplumbingwg/whereabouts
LABEL io.k8s.display-name="Whereabouts CNI" \
io.k8s.description="This is a component of OpenShift Container Platform and provides a cluster-wide IPAM CNI plugin." \
io.openshift.tags="openshift" \
maintainer="CTO Networking <[email protected]>"
io.k8s.description="This is a component of OpenShift Container Platform and provides a cluster-wide IPAM CNI plugin." \
io.openshift.tags="openshift" \
maintainer="CTO Networking <[email protected]>"
5 changes: 3 additions & 2 deletions doc/crds/daemonset-install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ spec:
command: [ "/bin/sh" ]
args:
- -c
- >
SLEEP=false /install-cni.sh &&
- |
SLEEP=false source /install-cni.sh
/token-watcher.sh &
/ip-control-loop -log-level debug
image: ghcr.io/k8snetworkplumbingwg/whereabouts:latest
env:
Expand Down
131 changes: 4 additions & 127 deletions script/install-cni.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,150 +10,27 @@ set -u -e
#
#SPDX-License-Identifier: Apache-2.0

CNI_BIN_DIR=${CNI_BIN_DIR:-"/host/opt/cni/bin/"}
WHEREABOUTS_KUBECONFIG_FILE_HOST=${WHEREABOUTS_KUBECONFIG_FILE_HOST:-"/etc/cni/net.d/whereabouts.d/whereabouts.kubeconfig"}
CNI_CONF_DIR=${CNI_CONF_DIR:-"/host/etc/cni/net.d"}
WHEREABOUTS_RECONCILER_CRON=${WHEREABOUTS_RECONCILER_CRON:-30 4 * * *}

# Make a whereabouts.d directory (for our kubeconfig)

mkdir -p $CNI_CONF_DIR/whereabouts.d
WHEREABOUTS_KUBECONFIG=$CNI_CONF_DIR/whereabouts.d/whereabouts.kubeconfig
WHEREABOUTS_CONF_FILE=$CNI_CONF_DIR/whereabouts.d/whereabouts.conf
WHEREABOUTS_KUBECONFIG_LITERAL=$(echo "$WHEREABOUTS_KUBECONFIG" | sed -e s'|/host||')

# ------------------------------- Generate a "kube-config"
SERVICE_ACCOUNT_PATH=/var/run/secrets/kubernetes.io/serviceaccount
KUBE_CA_FILE=${KUBE_CA_FILE:-$SERVICE_ACCOUNT_PATH/ca.crt}
SERVICE_ACCOUNT_TOKEN=$(cat $SERVICE_ACCOUNT_PATH/token)
SERVICE_ACCOUNT_TOKEN_PATH=$SERVICE_ACCOUNT_PATH/token
SKIP_TLS_VERIFY=${SKIP_TLS_VERIFY:-false}

LAST_SERVICEACCOUNT_MD5SUM=""
LAST_KUBE_CA_FILE_MD5SUM=""
source lib.sh

# Setup our logging routines

function log()
{
echo "$(date --iso-8601=seconds) ${1}"
}

function error()
{
log "ERR: {$1}"
}

function warn()
{
log "WARN: {$1}"
}


function generateKubeConfig {
# Check if we're running as a k8s pod.
if [ -f "$SERVICE_ACCOUNT_PATH/token" ]; then
# We're running as a k8d pod - expect some variables.
if [ -z ${KUBERNETES_SERVICE_HOST} ]; then
error "KUBERNETES_SERVICE_HOST not set"; exit 1;
fi
if [ -z ${KUBERNETES_SERVICE_PORT} ]; then
error "KUBERNETES_SERVICE_PORT not set"; exit 1;
fi

if [ "$SKIP_TLS_VERIFY" == "true" ]; then
TLS_CFG="insecure-skip-tls-verify: true"
elif [ -f "$KUBE_CA_FILE" ]; then
TLS_CFG="certificate-authority-data: $(cat $KUBE_CA_FILE | base64 | tr -d '\n')"
fi

# Kubernetes service address must be wrapped if it is IPv6 address
KUBERNETES_SERVICE_HOST_WRAP=$KUBERNETES_SERVICE_HOST
if [ "$KUBERNETES_SERVICE_HOST_WRAP" != "${KUBERNETES_SERVICE_HOST_WRAP#*:[0-9a-fA-F]}" ]; then
KUBERNETES_SERVICE_HOST_WRAP=\[$KUBERNETES_SERVICE_HOST_WRAP\]
fi

# Write a kubeconfig file for the CNI plugin. Do this
# to skip TLS verification for now. We should eventually support
# writing more complete kubeconfig files. This is only used
# if the provided CNI network config references it.
touch $WHEREABOUTS_KUBECONFIG
chmod ${KUBECONFIG_MODE:-600} $WHEREABOUTS_KUBECONFIG
cat > $WHEREABOUTS_KUBECONFIG <<EOF
# Kubeconfig file for the Whereabouts CNI plugin.
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
server: ${KUBERNETES_SERVICE_PROTOCOL:-https}://${KUBERNETES_SERVICE_HOST_WRAP}:${KUBERNETES_SERVICE_PORT}
$TLS_CFG
users:
- name: whereabouts
user:
token: "${SERVICE_ACCOUNT_TOKEN}"
contexts:
- name: whereabouts-context
context:
cluster: local
user: whereabouts
namespace: ${WHEREABOUTS_NAMESPACE}
current-context: whereabouts-context
EOF

else
warn "Doesn't look like we're running in a kubernetes environment (no serviceaccount token)"
fi

}

# -------------------Generate a "kube-config"
generateKubeConfig

export LAST_SERVICEACCOUNT_MD5SUM="$(get_token_md5sum)"
export LAST_KUBE_CA_FILE_MD5SUM="$(get_ca_file_md5sum)"
# ------------------ end Generate a "kube-config"

# ----------------- Generate a whereabouts conf

function generateWhereaboutsConf {

touch $WHEREABOUTS_CONF_FILE
chmod ${KUBECONFIG_MODE:-600} $WHEREABOUTS_CONF_FILE
cat > $WHEREABOUTS_CONF_FILE <<EOF
{
"datastore": "kubernetes",
"kubernetes": {
"kubeconfig": "${WHEREABOUTS_KUBECONFIG_LITERAL}"
},
"reconciler_cron_expression": "${WHEREABOUTS_RECONCILER_CRON}"
}
EOF

}

generateWhereaboutsConf

# ---------------- End generate a whereabouts conf



# copy whereabouts to the cni bin dir
cp -f /whereabouts $CNI_BIN_DIR

# ---------------------- end generate a "kube-config".

# enter sleep/watch loop

while true; do
# Check the md5sum of the service account token and ca.
svcaccountsum=$(md5sum $SERVICE_ACCOUNT_TOKEN_PATH | awk '{print $1}')
casum=$(md5sum $KUBE_CA_FILE | awk '{print $1}')
if [ "$svcaccountsum" != "$LAST_SERVICEACCOUNT_MD5SUM" ] || [ "$casum" != "$LAST_KUBE_CA_FILE_MD5SUM" ]; then
# log "Detected service account or CA file change, regenerating kubeconfig..."
generateKubeConfig
fi

sleep 1
done

# Unless told otherwise, sleep forever.
# This prevents Kubernetes from restarting the pod repeatedly.
should_sleep=${SLEEP:-"true"}
Expand Down
119 changes: 119 additions & 0 deletions script/lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
CNI_BIN_DIR=${CNI_BIN_DIR:-"/host/opt/cni/bin/"}
WHEREABOUTS_KUBECONFIG_FILE_HOST=${WHEREABOUTS_KUBECONFIG_FILE_HOST:-"/etc/cni/net.d/whereabouts.d/whereabouts.kubeconfig"}
CNI_CONF_DIR=${CNI_CONF_DIR:-"/host/etc/cni/net.d"}
WHEREABOUTS_RECONCILER_CRON=${WHEREABOUTS_RECONCILER_CRON:-30 4 * * *}

# Make a whereabouts.d directory (for our kubeconfig)

mkdir -p $CNI_CONF_DIR/whereabouts.d
WHEREABOUTS_KUBECONFIG=$CNI_CONF_DIR/whereabouts.d/whereabouts.kubeconfig
WHEREABOUTS_CONF_FILE=$CNI_CONF_DIR/whereabouts.d/whereabouts.conf
WHEREABOUTS_KUBECONFIG_LITERAL=$(echo "$WHEREABOUTS_KUBECONFIG" | sed -e s'|/host||')

SERVICE_ACCOUNT_PATH=/var/run/secrets/kubernetes.io/serviceaccount
KUBE_CA_FILE=${KUBE_CA_FILE:-$SERVICE_ACCOUNT_PATH/ca.crt}
SERVICE_ACCOUNT_TOKEN=$(cat $SERVICE_ACCOUNT_PATH/token)
SERVICE_ACCOUNT_TOKEN_PATH=$SERVICE_ACCOUNT_PATH/token
SKIP_TLS_VERIFY=${SKIP_TLS_VERIFY:-false}


function log()
{
echo "$(date -Iseconds) ${1}"
}

function error()
{
log "ERR: {$1}"
}

function warn()
{
log "WARN: {$1}"
}


function generateKubeConfig {
# Check if we're running as a k8s pod.
if [ -f "$SERVICE_ACCOUNT_PATH/token" ]; then
# We're running as a k8d pod - expect some variables.
if [ -z ${KUBERNETES_SERVICE_HOST} ]; then
error "KUBERNETES_SERVICE_HOST not set"; exit 1;
fi
if [ -z ${KUBERNETES_SERVICE_PORT} ]; then
error "KUBERNETES_SERVICE_PORT not set"; exit 1;
fi

if [ "$SKIP_TLS_VERIFY" == "true" ]; then
TLS_CFG="insecure-skip-tls-verify: true"
elif [ -f "$KUBE_CA_FILE" ]; then
TLS_CFG="certificate-authority-data: $(cat $KUBE_CA_FILE | base64 | tr -d '\n')"
fi

# Kubernetes service address must be wrapped if it is IPv6 address
KUBERNETES_SERVICE_HOST_WRAP=$KUBERNETES_SERVICE_HOST
if [ "$KUBERNETES_SERVICE_HOST_WRAP" != "${KUBERNETES_SERVICE_HOST_WRAP#*:[0-9a-fA-F]}" ]; then
KUBERNETES_SERVICE_HOST_WRAP=\[$KUBERNETES_SERVICE_HOST_WRAP\]
fi

# Write a kubeconfig file for the CNI plugin. Do this
# to skip TLS verification for now. We should eventually support
# writing more complete kubeconfig files. This is only used
# if the provided CNI network config references it.
touch $WHEREABOUTS_KUBECONFIG
chmod ${KUBECONFIG_MODE:-600} $WHEREABOUTS_KUBECONFIG
cat > $WHEREABOUTS_KUBECONFIG <<EOF
# Kubeconfig file for the Whereabouts CNI plugin.
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
server: ${KUBERNETES_SERVICE_PROTOCOL:-https}://${KUBERNETES_SERVICE_HOST_WRAP}:${KUBERNETES_SERVICE_PORT}
$TLS_CFG
users:
- name: whereabouts
user:
token: "${SERVICE_ACCOUNT_TOKEN}"
contexts:
- name: whereabouts-context
context:
cluster: local
user: whereabouts
namespace: ${WHEREABOUTS_NAMESPACE}
current-context: whereabouts-context
EOF

else
warn "Doesn't look like we're running in a kubernetes environment (no serviceaccount token)"
fi

}

function generateWhereaboutsConf {

touch $WHEREABOUTS_CONF_FILE
chmod ${KUBECONFIG_MODE:-600} $WHEREABOUTS_CONF_FILE
cat > $WHEREABOUTS_CONF_FILE <<EOF
{
"datastore": "kubernetes",
"kubernetes": {
"kubeconfig": "${WHEREABOUTS_KUBECONFIG_LITERAL}"
},
"reconciler_cron_expression": "${WHEREABOUTS_RECONCILER_CRON}"
}
EOF

}

function get_token_md5sum {
md5sum "$SERVICE_ACCOUNT_TOKEN_PATH" | awk '{print $1}'
}

function get_ca_file_md5sum {
if [ ! -f "$KUBE_CA_FILE" ]; then
echo ""
return
fi
md5sum "$KUBE_CA_FILE" | awk '{print $1}'
}
21 changes: 21 additions & 0 deletions script/token-watcher.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh

set -u -e

source lib.sh

echo "Sleep and Watching for service account token and CA file changes..."
# enter sleep/watch loop
while true; do
# Check the md5sum of the service account token and ca.
svcaccountsum="$(get_token_md5sum)"
casum="$(get_ca_file_md5sum)"
if [ "$svcaccountsum" != "$LAST_SERVICEACCOUNT_MD5SUM" ] || ! [ "$SKIP_TLS_VERIFY" == "true" ] && [ "$casum" != "$LAST_KUBE_CA_FILE_MD5SUM" ]; then
log "Detected service account or CA file change, regenerating kubeconfig..."
generateKubeConfig
LAST_SERVICEACCOUNT_MD5SUM="$svcaccountsum"
LAST_KUBE_CA_FILE_MD5SUM="$casum"
fi

sleep 1s
done
Loading