From 619fff4fcf998b8885b1672431ee87b77df0a5a5 Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Mon, 16 Aug 2021 17:59:29 +0200 Subject: [PATCH 1/7] Added SElinux as option at is required for mounting on SELinux enabled hosts Added SElinux as option at is required for mounting on SELinux enabled hosts. I found this issue when I was improving security for our environment. --- cifs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cifs b/cifs index 040674e..247d26a 100755 --- a/cifs +++ b/cifs @@ -98,6 +98,12 @@ doMount() { if [[ $? -ne 0 ]] ; then errorExit "cifs mount: option mountOptions missing in flexvolume configuration." fi + + selinuxOptions="" + selinuxEnabled="$(jq --raw-output -e '.selinuxEnabled' <<< "$json" 2>/dev/null)" + if [[ "$(echo $selinuxEnabled|tr '[A-Z]' '[a-z]')" == "true" ]] ; then + selinuxOptions=",context=system_u:object_r:container_file_t:s0" + fi cifsUsernameBase64="$(jq --raw-output -e '.["kubernetes.io/secret/username"]' <<< "$json" 2>/dev/null)" if [[ $? -ne 0 ]] ; then errorExit "cifs mount: username not found. the flexVolume definition must contain a secretRef to a secret with username and password." From 459398079082be0d73484895ef284430f13d95ef Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Mon, 16 Aug 2021 18:05:11 +0200 Subject: [PATCH 2/7] Added an example using selinuxEnabled option. By default it will not use any SElinux feature. Added an example using selinuxEnabled option. By default it will not use any SElinux feature. I added the following common SELinux labels (from Red Hat best practices with containers): selevel: s0 serole: object_r setype: container_file_t seuser: system_u Using container_file_t, containers will be available to manage mount content. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2f10481..2aa523d 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ spec: options: networkPath: "//server/share" mountOptions: "dir_mode=0755,file_mode=0644,noperm" + selinuxEnabled: "true" ``` Start the pod: From 6951ab4a9a2b225e2373734c3c85f02c8a424c69 Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Mon, 16 Aug 2021 18:12:43 +0200 Subject: [PATCH 3/7] Added SELinux options during mount operation --- cifs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cifs b/cifs index 247d26a..5ac2fe5 100755 --- a/cifs +++ b/cifs @@ -131,7 +131,7 @@ doMount() { fi export PASSWD="$cifsPassword" - result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions" 2>&1) + result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions$selinuxOptions" 2>&1) if [[ $? -ne 0 ]] ; then errorExit "cifs mount: failed to mount the network path: $result" fi From 6e00ebe870ce36ad6721c3fb4fb0108ee7275f9a Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Mon, 4 Jul 2022 10:04:05 +0200 Subject: [PATCH 4/7] Added Logging for debugging purposes --- cifs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cifs b/cifs index 5ac2fe5..4d8e751 100755 --- a/cifs +++ b/cifs @@ -2,6 +2,9 @@ set -u +DEBUG=0 +LOGFILE=/var/log/cifs.log + # ==================================================================== # Example configuration: # ==================================================================== @@ -54,12 +57,27 @@ set -u # date >> /tmp/cifs.log # echo "$@" >> /tmp/cifs.log +log() { + level=$1 + message=$2 + if ${DEBUG} -ne 0 + then + echo "${level}:${message}" >>${LOGFILE} + fi +} + +checkMount() { + runningprocesses="$(fuser -m $1)" + log "info" "Running Processes: ${runningprocesses}" +} + init() { assertBinaryInstalled mount.cifs cifs-utils assertBinaryInstalled jq jq assertBinaryInstalled mountpoint util-linux assertBinaryInstalled base64 coreutils echo '{ "status": "Success", "message": "The fstab/cifs flexvolume plugin was initialized successfully", "capabilities": { "attach": false } }' + log "info" "The fstab/cifs flexvolume plugin was initialized successfully" exit 0 } @@ -68,6 +86,7 @@ assertBinaryInstalled() { package="$2" if ! which "$binary" > /dev/null ; then errorExit "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package." + log "error" "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package." fi } @@ -77,6 +96,7 @@ errorExit() { else jq -Mcn --arg message "$1" '{ "status": "Failure", "message": $message }' fi + log "error" "$message" exit 1 } @@ -131,6 +151,9 @@ doMount() { fi export PASSWD="$cifsPassword" + + log "debug" "mount -t cifs \"$networkPath\" \"$mountPoint\" -o \"username=$cifsUsername,$mountOptions$selinuxOptions\"" + result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions$selinuxOptions" 2>&1) if [[ $? -ne 0 ]] ; then errorExit "cifs mount: failed to mount the network path: $result" @@ -147,6 +170,9 @@ doUnmount() { if [[ $(mountpoint "$mountPoint") != *"is a mountpoint"* ]] ; then errorExit "cifs unmount: no filesystem mounted under directory: '$mountPoint'" fi + + checkMount "$mountPoint" + result=$(umount "$mountPoint" 2>&1) if [[ $? -ne 0 ]] ; then errorExit "cifs unmount: failed to unmount the network path: $result" From 0fbc17c4cec0b82bce4e9e8885a496162ac7d3eb Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Thu, 4 Aug 2022 09:38:30 +0200 Subject: [PATCH 5/7] Updated script with Logging and fuser verification --- cifs | 245 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 126 insertions(+), 119 deletions(-) diff --git a/cifs b/cifs index 4d8e751..6b93de8 100755 --- a/cifs +++ b/cifs @@ -2,7 +2,7 @@ set -u -DEBUG=0 +DEBUG=1 LOGFILE=/var/log/cifs.log # ==================================================================== @@ -53,155 +53,162 @@ LOGFILE=/var/log/cifs.log # -------------------------------------------------------------------- # Uncomment the following lines to see how this plugin is called: -# echo >> /tmp/cifs.log -# date >> /tmp/cifs.log -# echo "$@" >> /tmp/cifs.log +#echo >> /tmp/cifs_.log +#date >> /tmp/cifs_.log +#echo "$@" >> /tmp/cifs_.log log() { - level=$1 - message=$2 - if ${DEBUG} -ne 0 - then - echo "${level}:${message}" >>${LOGFILE} - fi + level=$1 + message=$2 + if [ ${DEBUG} -ne 0 ] + then + echo "${level}:::${message}" >>${LOGFILE} + fi } checkMount() { - runningprocesses="$(fuser -m $1)" - log "info" "Running Processes: ${runningprocesses}" + log "debug" "verifying running processes..." + runningprocesses="$(fuser -m $1)" + [ -n "${runningprocesses}" ] && log "info" "Running Processes: ${runningprocesses}" + } init() { - assertBinaryInstalled mount.cifs cifs-utils - assertBinaryInstalled jq jq - assertBinaryInstalled mountpoint util-linux - assertBinaryInstalled base64 coreutils - echo '{ "status": "Success", "message": "The fstab/cifs flexvolume plugin was initialized successfully", "capabilities": { "attach": false } }' - log "info" "The fstab/cifs flexvolume plugin was initialized successfully" - exit 0 + assertBinaryInstalled mount.cifs cifs-utils + assertBinaryInstalled jq jq + assertBinaryInstalled mountpoint util-linux + assertBinaryInstalled base64 coreutils + echo '{ "status": "Success", "message": "The fstab/cifs flexvolume plugin was initialized successfully", "capabilities": { "attach": false } }' + log "debug" "The fstab/cifs flexvolume plugin was initialized successfully" + exit 0 } assertBinaryInstalled() { - binary="$1" - package="$2" - if ! which "$binary" > /dev/null ; then - errorExit "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package." - log "error" "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package." - fi + binary="$1" + package="$2" + if ! which "$binary" > /dev/null ; then + errorExit "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package." + fi } errorExit() { - if [[ $# -ne 1 ]] ; then - echo '{ "status": "Failure", "message": "Unknown error in the fstab/cifs flexvolume plugin." }' - else - jq -Mcn --arg message "$1" '{ "status": "Failure", "message": $message }' - fi - log "error" "$message" - exit 1 + if [[ $# -ne 1 ]] ; then + echo '{ "status": "Failure", "message": "Unknown error in the fstab/cifs flexvolume plugin." }' + log "error" "Unknown error in the fstab/cifs flexvolume plugin.." + else + jq -Mcn --arg message "$1" '{ "status": "Failure", "message": $message }' + log "error" "$1" + fi + exit 1 } doMount() { - if [[ -z ${1:-} || -z ${2:-} ]] ; then - errorExit "cifs mount: syntax error. usage: cifs mount " - fi - mountPoint="$1" - shift - json=$(printf '%s ' "${@}") - if ! jq -e . > /dev/null 2>&1 <<< "$json" ; then - errorExit "cifs mount: syntax error. invalid json: '$json'" - fi - networkPath="$(jq --raw-output -e '.networkPath' <<< "$json" 2>/dev/null)" - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: option networkPath missing in flexvolume configuration." - fi - mountOptions="$(jq --raw-output -e '.mountOptions' <<< "$json" 2>/dev/null)" - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: option mountOptions missing in flexvolume configuration." - fi - - selinuxOptions="" + log "info" "mount action - $1 '$2'" + if [[ -z ${1:-} || -z ${2:-} ]] ; then + errorExit "cifs mount: syntax error. usage: cifs mount " + fi + mountPoint="$1" + shift + json=$(printf '%s ' "${@}") + if ! jq -e . > /dev/null 2>&1 <<< "$json" ; then + errorExit "cifs mount: syntax error. invalid json: '$json'" + fi + networkPath="$(jq --raw-output -e '.networkPath' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: option networkPath missing in flexvolume configuration." + fi + mountOptions="$(jq --raw-output -e '.mountOptions' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: option mountOptions missing in flexvolume configuration." + fi + + selinuxOptions="" selinuxEnabled="$(jq --raw-output -e '.selinuxEnabled' <<< "$json" 2>/dev/null)" if [[ "$(echo $selinuxEnabled|tr '[A-Z]' '[a-z]')" == "true" ]] ; then selinuxOptions=",context=system_u:object_r:container_file_t:s0" - fi - cifsUsernameBase64="$(jq --raw-output -e '.["kubernetes.io/secret/username"]' <<< "$json" 2>/dev/null)" - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: username not found. the flexVolume definition must contain a secretRef to a secret with username and password." - fi - cifsPasswordBase64="$(jq --raw-output -e '.["kubernetes.io/secret/password"]' <<< "$json" 2>/dev/null)" - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: password not found. the flexVolume definition must contain a secretRef to a secret with username and password." - fi - cifsUsername="$(base64 --decode <<< "$cifsUsernameBase64" 2>/dev/null)" - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: username secret is not base64 encoded." - fi - cifsPassword="$(base64 --decode <<< "$cifsPasswordBase64" 2>/dev/null)" - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: password secret is not base64 encoded." - fi - if ! mkdir -p "$mountPoint" > /dev/null 2>&1 ; then - errorExit "cifs mount: failed to create mount directory: '$mountPoint'" - fi - if [[ $(mountpoint "$mountPoint") = *"is a mountpoint"* ]] ; then - errorExit "cifs mount: there is already a filesystem mounted under the mount directory: '$mountPoint'" - fi - if [[ ! -z $(ls -A "$mountPoint" 2>/dev/null) ]] ; then - errorExit "cifs mount: mount directory is not an empty directory: '$mountPoint'" - fi - - export PASSWD="$cifsPassword" - - log "debug" "mount -t cifs \"$networkPath\" \"$mountPoint\" -o \"username=$cifsUsername,$mountOptions$selinuxOptions\"" - - result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions$selinuxOptions" 2>&1) - if [[ $? -ne 0 ]] ; then - errorExit "cifs mount: failed to mount the network path: $result" - fi - echo '{ "status": "Success" }' - exit 0 + fi + cifsUsernameBase64="$(jq --raw-output -e '.["kubernetes.io/secret/username"]' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: username not found. the flexVolume definition must contain a secretRef to a secret with username and password." + fi + cifsPasswordBase64="$(jq --raw-output -e '.["kubernetes.io/secret/password"]' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: password not found. the flexVolume definition must contain a secretRef to a secret with username and password." + fi + cifsUsername="$(base64 --decode <<< "$cifsUsernameBase64" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: username secret is not base64 encoded." + fi + cifsPassword="$(base64 --decode <<< "$cifsPasswordBase64" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: password secret is not base64 encoded." + fi + if ! mkdir -p "$mountPoint" > /dev/null 2>&1 ; then + errorExit "cifs mount: failed to create mount directory: '$mountPoint'" + fi + if [[ $(mountpoint "$mountPoint") = *"is a mountpoint"* ]] ; then + errorExit "cifs mount: there is already a filesystem mounted under the mount directory: '$mountPoint'" + fi + if [[ ! -z $(ls -A "$mountPoint" 2>/dev/null) ]] ; then + errorExit "cifs mount: mount directory is not an empty directory: '$mountPoint'" + fi + + export PASSWD="$cifsPassword" + + log "debug" "mount -t cifs \"$networkPath\" \"$mountPoint\" -o \"username=$cifsUsername,$mountOptions$selinuxOptions\"" + + result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions$selinuxOptions" 2>&1) + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: failed to mount the network path: $result" + fi + echo '{ "status": "Success" }' + log "info" "success mount" + exit 0 } doUnmount() { - if [[ -z ${1:-} ]] ; then - errorExit "cifs unmount: syntax error. usage: cifs unmount " - fi - mountPoint="$1" - if [[ $(mountpoint "$mountPoint") != *"is a mountpoint"* ]] ; then - errorExit "cifs unmount: no filesystem mounted under directory: '$mountPoint'" - fi - - checkMount "$mountPoint" - - result=$(umount "$mountPoint" 2>&1) - if [[ $? -ne 0 ]] ; then - errorExit "cifs unmount: failed to unmount the network path: $result" - fi - echo '{ "status": "Success" }' - exit 0 + log "info" "umount action - '$2'" + if [[ -z ${1:-} ]] ; then + errorExit "cifs unmount: syntax error. usage: cifs unmount " + fi + mountPoint="$1" + if [[ $(mountpoint "$mountPoint") != *"is a mountpoint"* ]] ; then + errorExit "cifs unmount: no filesystem mounted under directory: '$mountPoint'" + fi + + checkMount "$mountPoint" + + result=$(umount "$mountPoint" 2>&1) + if [[ $? -ne 0 ]] ; then + errorExit "cifs unmount: failed to unmount the network path: $result" + fi + echo '{ "status": "Success" }' + log "info" "success umount" + exit 0 } not_supported() { - echo '{ "status": "Not supported" }' - exit 1 + echo '{ "status": "Not supported" }' + log "info" "action not supported - ${@}" + exit 1 } command=${1:-} if [[ -n $command ]]; then - shift + shift fi case "$command" in - init) - init "$@" - ;; - mount) - doMount "$@" - ;; - unmount) - doUnmount "$@" - ;; - *) - not_supported "$@" - ;; + init) + init "$@" + ;; + mount) + doMount "$@" + ;; + unmount) + doUnmount "$@" + ;; + *) + not_supported "$@" + ;; esac From f4112d6c5af7c401dce6591c323d2346959e2cdb Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Thu, 4 Aug 2022 12:10:00 +0200 Subject: [PATCH 6/7] Added logsize check --- cifs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/cifs b/cifs index 6b93de8..3d4b2d8 100755 --- a/cifs +++ b/cifs @@ -4,6 +4,7 @@ set -u DEBUG=1 LOGFILE=/var/log/cifs.log +MAXLOGFILESIZE=100 # In megabytes # ==================================================================== # Example configuration: @@ -52,20 +53,24 @@ LOGFILE=/var/log/cifs.log # mountOptions: "dir_mode=0755,file_mode=0644,noperm" # -------------------------------------------------------------------- -# Uncomment the following lines to see how this plugin is called: -#echo >> /tmp/cifs_.log -#date >> /tmp/cifs_.log -#echo "$@" >> /tmp/cifs_.log log() { level=$1 - message=$2 + shift + message=$@ + shift if [ ${DEBUG} -ne 0 ] then - echo "${level}:::${message}" >>${LOGFILE} + echo "$(date +%Y%m%d-%H:%M:%S):::${level}:::${message}" >>${LOGFILE} fi } +manageSize(){ + [ ! -f ${LOGFILE} ] && log "info" "log initialized" && return + [ $(du -sm ${LOGFILE}|cut -f1) -gt ${MAXLOGFILESIZE} ] && mv ${LOGFILE} ${LOGFILE}.1 && log "info" "log initialized" + +} + checkMount() { log "debug" "verifying running processes..." runningprocesses="$(fuser -m $1)" @@ -103,7 +108,6 @@ errorExit() { } doMount() { - log "info" "mount action - $1 '$2'" if [[ -z ${1:-} || -z ${2:-} ]] ; then errorExit "cifs mount: syntax error. usage: cifs mount " fi @@ -155,7 +159,7 @@ doMount() { export PASSWD="$cifsPassword" - log "debug" "mount -t cifs \"$networkPath\" \"$mountPoint\" -o \"username=$cifsUsername,$mountOptions$selinuxOptions\"" + log "debug" "mount -t cifs $networkPath $mountPoint -o username=$cifsUsername,$mountOptions$selinuxOptions" result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions$selinuxOptions" 2>&1) if [[ $? -ne 0 ]] ; then @@ -167,7 +171,7 @@ doMount() { } doUnmount() { - log "info" "umount action - '$2'" + #log "info" "umount action - '$2'" if [[ -z ${1:-} ]] ; then errorExit "cifs unmount: syntax error. usage: cifs unmount " fi @@ -193,6 +197,11 @@ not_supported() { exit 1 } +# Uncomment the following lines to see how this plugin is called: +#echo >> /tmp/ci0fs_.log +manageSize +log "debug" "RAWDATA $@" + command=${1:-} if [[ -n $command ]]; then shift @@ -203,9 +212,11 @@ case "$command" in init "$@" ;; mount) + log "debug" "mount action - '$@'" doMount "$@" ;; unmount) + log "debug" "unmount action - '$@'" doUnmount "$@" ;; *) From 643c8eb623cc722842f7c33a88bcf3190f5d9d6d Mon Sep 17 00:00:00 2001 From: Javier Ramirez Date: Thu, 4 Aug 2022 12:15:04 +0200 Subject: [PATCH 7/7] Added execution details --- cifs | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/cifs b/cifs index 3d4b2d8..67cfba7 100755 --- a/cifs +++ b/cifs @@ -223,3 +223,231 @@ case "$command" in not_supported "$@" ;; esac +root@atlhqmphsrncd4:~# vi /var/lib/kubelet/volumeplugins/fstab~cifs/cifs +root@atlhqmphsrncd4:~# cat /var/lib/kubelet/volumeplugins/fstab~cifs/cifs +#!/bin/bash + +set -u + +DEBUG=1 +LOGFILE=/var/log/cifs.log +MAXLOGFILESIZE=100 # In megabytes + +# ==================================================================== +# Example configuration: +# ==================================================================== +# -------------------------------------------------------------------- +# secret.yml: +# -------------------------------------------------------------------- +# apiVersion: v1 +# kind: Secret +# metadata: +# name: cifs-secret +# namespace: default +# type: fstab/cifs +# data: +# username: 'ZXhhbXBsZQo=' +# password: 'c2VjcmV0Cg==' +# +# -------------------------------------------------------------------- +# pod.yml: +# -------------------------------------------------------------------- +# apiVersion: v1 +# kind: Pod +# metadata: +# name: busybox +# namespace: default +# spec: +# containers: +# - name: busybox +# image: busybox +# command: +# - sleep +# - "3600" +# imagePullPolicy: IfNotPresent +# volumeMounts: +# - name: test +# mountPath: /data +# volumes: +# - name: test +# flexVolume: +# driver: "fstab/cifs" +# fsType: "cifs" +# secretRef: +# name: "cifs-secret" +# options: +# networkPath: "//example-server/backup" +# mountOptions: "dir_mode=0755,file_mode=0644,noperm" +# -------------------------------------------------------------------- + + +log() { + level=$1 + shift + message=$@ + shift + if [ ${DEBUG} -ne 0 ] + then + echo "$(date +%Y%m%d-%H:%M:%S):::${level}:::${message}" >>${LOGFILE} + fi +} + +manageSize(){ + [ ! -f ${LOGFILE} ] && log "info" "log initialized" && return + [ $(du -sm ${LOGFILE}|cut -f1) -gt ${MAXLOGFILESIZE} ] && mv ${LOGFILE} ${LOGFILE}.1 && log "info" "log initialized" + +} + +checkMount() { + log "debug" "verifying running processes..." + runningprocesses="$(fuser -m $1)" + [ -n "${runningprocesses}" ] && log "info" "Running Processes: ${runningprocesses}" + +} + +init() { + assertBinaryInstalled mount.cifs cifs-utils + assertBinaryInstalled jq jq + assertBinaryInstalled mountpoint util-linux + assertBinaryInstalled base64 coreutils + echo '{ "status": "Success", "message": "The fstab/cifs flexvolume plugin was initialized successfully", "capabilities": { "attach": false } }' + log "debug" "The fstab/cifs flexvolume plugin was initialized successfully" + exit 0 +} + +assertBinaryInstalled() { + binary="$1" + package="$2" + if ! which "$binary" > /dev/null ; then + errorExit "Failed to initialize the fstab/cifs flexvolume plugin. $binary command not found. Please install the $package package." + fi +} + +errorExit() { + if [[ $# -ne 1 ]] ; then + echo '{ "status": "Failure", "message": "Unknown error in the fstab/cifs flexvolume plugin." }' + log "error" "Unknown error in the fstab/cifs flexvolume plugin.." + else + jq -Mcn --arg message "$1" '{ "status": "Failure", "message": $message }' + log "error" "$1" + fi + exit 1 +} + +doMount() { + if [[ -z ${1:-} || -z ${2:-} ]] ; then + errorExit "cifs mount: syntax error. usage: cifs mount " + fi + mountPoint="$1" + shift + json=$(printf '%s ' "${@}") + if ! jq -e . > /dev/null 2>&1 <<< "$json" ; then + errorExit "cifs mount: syntax error. invalid json: '$json'" + fi + networkPath="$(jq --raw-output -e '.networkPath' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: option networkPath missing in flexvolume configuration." + fi + mountOptions="$(jq --raw-output -e '.mountOptions' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: option mountOptions missing in flexvolume configuration." + fi + + selinuxOptions="" + selinuxEnabled="$(jq --raw-output -e '.selinuxEnabled' <<< "$json" 2>/dev/null)" + if [[ "$(echo $selinuxEnabled|tr '[A-Z]' '[a-z]')" == "true" ]] ; then + selinuxOptions=",context=system_u:object_r:container_file_t:s0" + fi + cifsUsernameBase64="$(jq --raw-output -e '.["kubernetes.io/secret/username"]' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: username not found. the flexVolume definition must contain a secretRef to a secret with username and password." + fi + cifsPasswordBase64="$(jq --raw-output -e '.["kubernetes.io/secret/password"]' <<< "$json" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: password not found. the flexVolume definition must contain a secretRef to a secret with username and password." + fi + cifsUsername="$(base64 --decode <<< "$cifsUsernameBase64" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: username secret is not base64 encoded." + fi + cifsPassword="$(base64 --decode <<< "$cifsPasswordBase64" 2>/dev/null)" + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: password secret is not base64 encoded." + fi + if ! mkdir -p "$mountPoint" > /dev/null 2>&1 ; then + errorExit "cifs mount: failed to create mount directory: '$mountPoint'" + fi + if [[ $(mountpoint "$mountPoint") = *"is a mountpoint"* ]] ; then + errorExit "cifs mount: there is already a filesystem mounted under the mount directory: '$mountPoint'" + fi + if [[ ! -z $(ls -A "$mountPoint" 2>/dev/null) ]] ; then + errorExit "cifs mount: mount directory is not an empty directory: '$mountPoint'" + fi + + export PASSWD="$cifsPassword" + + log "debug" "executed mount -t cifs $networkPath $mountPoint -o username=$cifsUsername,$mountOptions$selinuxOptions" + + result=$(mount -t cifs "$networkPath" "$mountPoint" -o "username=$cifsUsername,$mountOptions$selinuxOptions" 2>&1) + if [[ $? -ne 0 ]] ; then + errorExit "cifs mount: failed to mount the network path: $result" + fi + echo '{ "status": "Success" }' + log "info" "success mount" + exit 0 +} + +doUnmount() { + #log "info" "umount action - '$2'" + if [[ -z ${1:-} ]] ; then + errorExit "cifs unmount: syntax error. usage: cifs unmount " + fi + mountPoint="$1" + if [[ $(mountpoint "$mountPoint") != *"is a mountpoint"* ]] ; then + errorExit "cifs unmount: no filesystem mounted under directory: '$mountPoint'" + fi + + checkMount "$mountPoint" + + log "debug" "executed umount $mountPoint" + result=$(umount "$mountPoint" 2>&1|tr '\n' ' ') + if [[ $? -ne 0 ]] ; then + errorExit "cifs unmount: failed to unmount the network path: $result" + fi + echo '{ "status": "Success" }' + log "info" "success umount" + exit 0 +} + +not_supported() { + echo '{ "status": "Not supported" }' + log "info" "action not supported - ${@}" + exit 1 +} + +# Uncomment the following lines to see how this plugin is called: +#echo >> /tmp/ci0fs_.log +manageSize +log "debug" "RAWDATA $@" + +command=${1:-} +if [[ -n $command ]]; then + shift +fi + +case "$command" in + init) + init "$@" + ;; + mount) + log "debug" "mount action - '$@'" + doMount "$@" + ;; + unmount) + log "debug" "unmount action - '$@'" + doUnmount "$@" + ;; + *) + not_supported "$@" + ;; +esac