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
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#
ARG GOIMAGE
ARG BASEIMAGE
ARG VERSION="2.17.0"
ARG VERSION="2.17.1"

# Stage to build the driver
FROM $GOIMAGE as builder
Expand All @@ -35,7 +35,7 @@ LABEL vendor="Dell Technologies" \
name="csi-powermax" \
summary="CSI Driver for Dell EMC PowerMax" \
description="CSI Driver for provisioning persistent storage from Dell EMC PowerMax" \
release="1.17.0" \
release="1.17.1" \
version=$VERSION \
license="Apache-2.0"
COPY ./licenses /licenses
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ To run unit tests, execute `make unit-test`.
To build an image, execute `make docker`.

You can run an integration test on a Linux system by populating the file `env.sh` with values for your Dell PowerMax systems and then run "`make integration-test`".

## Runtime Dependencies
For a complete list of dependencies, please visit [Prerequisites](https://dell.github.io/csm-docs/docs/deployment/helm/drivers/installation/powermax/#prerequisites)


## Documentation
For more detailed information on the driver, please refer to [Container Storage Modules documentation](https://dell.github.io/csm-docs/).
2 changes: 1 addition & 1 deletion csireverseproxy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
############################
ARG GOIMAGE
ARG BASEIMAGE
ARG VERSION="2.16.0"
ARG VERSION="2.16.1"

FROM $GOIMAGE as builder

Expand Down
2 changes: 1 addition & 1 deletion csireverseproxy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.26.0

require (
github.com/dell/csmlog v1.1.0
github.com/dell/gopowermax/v2 v2.13.0
github.com/dell/gopowermax/v2 v2.13.1
github.com/fsnotify/fsnotify v1.10.1
github.com/gorilla/mux v1.8.1
github.com/kubernetes-csi/csi-lib-utils v0.23.0
Expand Down
4 changes: 2 additions & 2 deletions csireverseproxy/go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/dell/csmlog v1.1.0 h1:M2pi9a/xTI2FtQNruOoCs2LPACsdJIqPmtUYIH3Y2cI=
github.com/dell/csmlog v1.1.0/go.mod h1:+I49NJrSPD8DhS7PY37vfIwM0lIHAvGm22zRoMG2ygU=
github.com/dell/gopowermax/v2 v2.13.0 h1:bsEUfKyEeLCFksZ86I1kJJNmSEELzB8lZi9j0qyT6jk=
github.com/dell/gopowermax/v2 v2.13.0/go.mod h1:F2DSQ9MlqryFRu9tmX/p1V4bw2ZBZbRhEa/kut+Qfg8=
github.com/dell/gopowermax/v2 v2.13.1 h1:CXPXrTKFjgP0/HVR6zrd/K5UBKJAqos9buNNM2m/E2E=
github.com/dell/gopowermax/v2 v2.13.1/go.mod h1:F2DSQ9MlqryFRu9tmX/p1V4bw2ZBZbRhEa/kut+Qfg8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down
94 changes: 90 additions & 4 deletions csireverseproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type RevProxy interface {
ServeReverseProxy(res http.ResponseWriter, req *http.Request)
UpdateConfig(proxyConfig config.ProxyConfig) error
GetRouter() http.Handler
SetAuthToken(token string)
}

// ServerOpts - Proxy server configuration
Expand Down Expand Up @@ -127,10 +128,69 @@ func (s *Server) Config() *config.ProxyConfig {
return s.config
}

// isSidecarMode detects if running as sidecar by checking multiple indicators
func isSidecarMode() bool {
// Method 1: Check the DeployAsSidecar environment variable set by the operator
// In sidecar mode, the operator sets DeployAsSidecar=true
deployAsSidecar := getEnv("DeployAsSidecar", "") // No default for more accurate detection

// Method 2: Check if we're running in the same pod as CSI driver containers
// by checking for CSI driver environment variables or container presence

// Check for CSI driver specific environment variables that indicate sidecar mode
csiDriverEnvVars := []string{
"X_CSI_POWERMAX_ENDPOINT",
"X_CSI_POWERMAX_USER",
"X_CSI_POWERMAX_PASSWORD",
"X_CSI_POWERMAX_NODENAME",
"X_CSI_POWERMAX_PORTGROUPS",
}

hasCSIEnvVars := false
for _, envVar := range csiDriverEnvVars {
if getEnv(envVar, "") != "" {
hasCSIEnvVars = true
break
}
}

// Method 3: Check pod name and namespace patterns
podName := getEnv("POD_NAME", "")

// CSI driver pods typically have specific naming patterns
isCSIDriverPod := strings.Contains(podName, "controller") ||
strings.Contains(podName, "node") ||
strings.Contains(podName, "csi-")

// Debug logging to understand the mode detection
log.Infof("DeployAsSidecar environment variable: '%s'", deployAsSidecar)
log.Infof("Has CSI driver environment variables: %t", hasCSIEnvVars)
log.Infof("Pod name: '%s', Is CSI driver pod: %t", podName, isCSIDriverPod)

// Determine sidecar mode based on multiple indicators
isSidecar := false

// Primary check: DeployAsSidecar environment variable explicitly set
if deployAsSidecar != "" {
lowerValue := strings.ToLower(strings.TrimSpace(deployAsSidecar))
isSidecar = lowerValue == "true" || lowerValue == "1" || lowerValue == "yes"
log.Infof("DeployAsSidecar explicitly set, sidecar mode: %t", isSidecar)
} else {
// Fallback check: If we have CSI driver env vars and are in a CSI driver pod
isSidecar = hasCSIEnvVars && isCSIDriverPod
log.Infof("DeployAsSidecar not set, using fallback detection, sidecar mode: %t", isSidecar)
}

log.Infof("Final sidecar mode determination: %t", isSidecar)
return isSidecar
}

// Setup sets up the server and the proxy configuration
// this includes - reading the secret or config map, creating appropriate proxy instance
// and setting up the signal handler channel
func (s *Server) Setup(k8sUtils k8sutils.UtilsInterface) error {
// Auth token validation is handled during loading in the proxy configuration section below

// Read the config from secret if secret provided
if getEnv(common.EnvReverseProxyUseSecret, "false") == "true" {
log.Info("Reading config using secret")
Expand Down Expand Up @@ -212,6 +272,32 @@ func (s *Server) Setup(k8sUtils k8sutils.UtilsInterface) error {
s.SigChan = make(chan os.Signal, 1)
}

// Load shared auth token if configured
// Note: Auth token is only used in standalone mode, not in sidecar mode
isSidecar := isSidecarMode()
if tokenFile := getEnv(common.EnvProxyAuthTokenFile, ""); tokenFile != "" {
if isSidecar {
log.Info("Sidecar deployment detected - auth token is not used in sidecar mode, skipping")
// Skip auth token loading entirely in sidecar mode
} else {
log.Info("Standalone deployment detected - loading auth token")
tokenBytes, err := os.ReadFile(filepath.Clean(tokenFile))
if err != nil {
log.Warnf("Proxy auth token file %s not found or not readable in standalone mode, continuing without auth token: %v", tokenFile, err)
// Continue deployment without auth token - don't fail
} else {
token := strings.TrimSpace(string(tokenBytes))
if token == "" {
log.Warnf("Proxy auth token file %s is empty in standalone mode, continuing without auth token", tokenFile)
// Continue deployment without auth token - don't fail
} else {
s.Proxy.SetAuthToken(token)
log.Info("Proxy auth token loaded successfully for standalone deployment")
}
}
}
}

return nil
}

Expand Down Expand Up @@ -314,7 +400,7 @@ func (s *Server) SetupConfigWatcher(k8sUtils k8sutils.UtilsInterface, v *viper.V
}

func (s *Server) configChangeConfigMap(k8sUtils k8sutils.UtilsInterface, vcm *viper.Viper) {
log.Infof("Received a config change event for configmap - all settings %v", vcm.AllSettings())
log.Infof("Received a config change event for configmap - all settings")
var proxyConfigMap config.ProxyConfigMap
err := vcm.Unmarshal(&proxyConfigMap)
if err != nil {
Expand All @@ -336,12 +422,12 @@ func (s *Server) configChangeConfigMap(k8sUtils k8sutils.UtilsInterface, vcm *vi
if err != nil {
log.Errorf("Error in updating the config: %s", err.Error())
}
log.Infof("Updated proxy config: %+v", proxyConfig)
log.Infof("Updated proxy config")
}
}

func (s *Server) configChangeSecret(k8sUtils k8sutils.UtilsInterface, vs *viper.Viper) {
log.Infof("Received a config change event for secret - all settings %v", vs.AllSettings())
log.Info("Received a config change event for secret")
var proxySecret config.ProxySecret
err := vs.Unmarshal(&proxySecret)
if err != nil {
Expand All @@ -361,7 +447,7 @@ func (s *Server) configChangeSecret(k8sUtils k8sutils.UtilsInterface, vs *viper.
}

func (s *Server) configChangeParamsConfigMap(k8sUtils k8sutils.UtilsInterface, vcmp *viper.Viper) {
log.Infof("Received a config change event for params configmap - all settings %v", vcmp.AllSettings())
log.Infof("Received a config change event for params configmap")
var ParamsConfigMap config.ParamsConfigMap
err := vcmp.Unmarshal(&ParamsConfigMap)
if err != nil {
Expand Down
Loading
Loading