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
8 changes: 5 additions & 3 deletions .dagger/src/operator_flows/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,16 @@ async def copy_k8s_secret_from_one_cluster_to_another(

# Create the secret directly using kubectl create secret generic with the data
logger.info(f"Creating secret {target_secret_name} in target cluster")


# SECURITY NOTE: secret_data is base64-encoded (Kubernetes default) and embedded in heredoc.
# Heredoc prevents shell injection, but avoid logging this command to prevent secret exposure.
# Use kubectl to create the secret from the extracted data
create_secret_cmd = [
"sh", "-c",
"sh", "-c",
f"""
# Delete the secret if it already exists (ignore errors)
kubectl --kubeconfig=/.kube/target/config delete secret {target_secret_name} -n {target_namespace} || true

# Create a temporary YAML file with the secret
cat <<EOF > /tmp/secret.yaml
apiVersion: v1
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/dagger_ci_on_merge_queue_plan.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ jobs:
chmod 600 ${{ github.workspace }}/.kube/config

- name: Call Generate Test Artifacts
uses: dagger/dagger-for-github@8.0.0
uses: dagger/dagger-for-github@v8.2.0
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
Expand All @@ -171,7 +171,7 @@ jobs:
retention-days: 1

- name: Publish Operator
uses: dagger/dagger-for-github@8.0.0
uses: dagger/dagger-for-github@v8.2.0
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
with:
Expand Down Expand Up @@ -210,7 +210,7 @@ jobs:
find ${{ github.workspace }}/test-artifacts -type f -name "*.sh" -exec ls -la {} \; || echo "No .sh files found"

- name: Run Upgrade-extended Test
uses: dagger/dagger-for-github@8.0.0
uses: dagger/dagger-for-github@v8.2.0
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
Expand Down Expand Up @@ -295,7 +295,7 @@ jobs:
chmod 600 ${{ github.workspace }}/.kube/ocp-cluster-config

- name: Run OCP Clients-Only Test
uses: dagger/dagger-for-github@8.0.0
uses: dagger/dagger-for-github@v8.2.0
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
with:
Expand Down
15 changes: 11 additions & 4 deletions .github/workflows/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ jobs:
with:
version: v3.16.3
- name: Login to Registry
run: helm registry login quay.io/weka.io --username ${{ secrets.QuayUsername }} --password ${{ secrets.QuayPassword }}
env:
QUAY_USERNAME: ${{ secrets.QuayUsername }}
QUAY_PASSWORD: ${{ secrets.QuayPassword }}
run: helm registry login quay.io/weka.io --username "$QUAY_USERNAME" --password "$QUAY_PASSWORD"
- name: Configure git
run: |
git config user.name "$GITHUB_ACTOR"
Expand All @@ -115,22 +118,26 @@ jobs:
- name: Read VERSION from inputs
id: version_input
if: github.event_name == 'workflow_dispatch'
run: echo "VERSION=${{ github.event.inputs.version-name }}" >> $GITHUB_ENV
env:
VERSION_INPUT: ${{ github.event.inputs.version-name }}
run: echo "VERSION=$VERSION_INPUT" >> $GITHUB_ENV
- name: Read VERSION file
id: version
if: github.event_name != 'workflow_dispatch'
run: echo "VERSION=$(cat .VERSION)" >> $GITHUB_ENV
- name: build version
if: ${{ env.VERSION != '' }}
run: VERSION=${{ env.VERSION }} ./build-release.sh
env:
VERSION: ${{ env.VERSION }}
run: ./build-release.sh
- name: Create release
if: ${{ env.VERSION != '' && github.event_name != 'workflow_dispatch' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run release
- name: Add operator version as artifact
if: ${{ env.VERSION != '' }}
run: echo "${{ env.VERSION }}" > operator-version.txt
run: echo "$VERSION" > operator-version.txt
- name: Upload artifact
if: ${{ env.VERSION != '' }}
uses: actions/upload-artifact@v4
Expand Down
100 changes: 0 additions & 100 deletions .github/workflows/pr_ai_test.yaml

This file was deleted.

19 changes: 12 additions & 7 deletions .github/workflows/run_upgrade_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,22 @@ jobs:
- name: Make binary executable
run: chmod +x ./weka-k8s-testing
- name: Run upgrade test
env:
INITIAL_VERSION: ${{ github.event.inputs.weka-initial-version || 'quay.io/weka.io/weka-in-container:4.4.5.118-k8s.' }}
NEW_VERSION: ${{ github.event.inputs.weka-new-version || 'quay.io/weka.io/weka-in-container:4.4.10.183' }}
OPERATOR_VERSION_INPUT: ${{ env.OPERATOR_VERSION || github.event.inputs.operator-version }}
DO_CLEANUP: ${{ github.event.inputs.do_cleanup }}
run: |
cleanup=""
if [[ "${{ github.event.inputs.do_cleanup }}" == "false" ]]; then
if [[ "$DO_CLEANUP" == "false" ]]; then
cleanup="--cleanup no-cleanup"
fi

./weka-k8s-testing upgrade-extended \
--initial-version ${{ github.event.inputs.weka-initial-version || 'quay.io/weka.io/weka-in-container:4.4.5.118-k8s.' }} \
--new-version ${{ github.event.inputs.weka-new-version || 'quay.io/weka.io/weka-in-container:4.4.10.183' }} \
--operator-version ${{ env.OPERATOR_VERSION || github.event.inputs.operator-version }} \
--node-selector weka.io/dedicated:upgrade-extended \
--namespace test-upgrade-extended \
--cluster-name upgrade-extended \
--initial-version "$INITIAL_VERSION" \
--new-version "$NEW_VERSION" \
--operator-version "$OPERATOR_VERSION_INPUT" \
--node-selector "weka.io/dedicated:upgrade-extended" \
--namespace "test-upgrade-extended" \
--cluster-name "upgrade-extended" \
$cleanup
3 changes: 3 additions & 0 deletions charts/weka-operator/resources/weka_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2413,6 +2413,9 @@ async def create_container():
{f"--restricted" if MODE == 'client' and "4.2.7.64" not in IMAGE_NAME else ""} \
{f"--failure-domain {failure_domain}" if failure_domain else ""}
""")
# join_secret_cmd is a shell command substitution "$(cat /path/to/secret)", not the secret value itself
# The actual secret is read by the shell at runtime and never appears in this logged string
# lgtm[py/clear-text-logging-sensitive-data]
logging.info(f"Creating container with command: {command}")
stdout, stderr, ec = await run_command(command)
if ec != 0:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package wekacontainer

import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"path"
Expand Down Expand Up @@ -232,7 +233,9 @@ func (r *containerReconcilerLoop) sendStopInstructionsViaAgent(ctx context.Conte
instructionsBasePath := path.Join(resources.GetPodShutdownInstructionPathOnAgent(nodeInfo.BootID, pod))
instructionsPath := path.Join(instructionsBasePath, "shutdown_instructions.json")

_, _, err = executor.ExecNamed(ctx, "StopInstructionsViaAgent", []string{"bash", "-ce", fmt.Sprintf("mkdir -p '%s' && echo '%s' > '%s'", instructionsBasePath, instructionsJson, instructionsPath)})
// Use base64 encoding to safely pass JSON through shell
instructionsB64 := base64.StdEncoding.EncodeToString(instructionsJson)
_, _, err = executor.ExecNamed(ctx, "StopInstructionsViaAgent", []string{"bash", "-ce", fmt.Sprintf("mkdir -p '%s' && echo '%s' | base64 -d > '%s'", instructionsBasePath, instructionsB64, instructionsPath)})
if err != nil {
logger.Error(err, "Error writing stop instructions via node-agent")
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package wekacontainer

import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"go/types"
Expand Down Expand Up @@ -174,14 +175,17 @@ func (r *containerReconcilerLoop) WriteResources(ctx context.Context) error {
return err
}

// Use base64 encoding for safe file writing - prevents bash injection issues
// Use base64 encoding to safely pass JSON through shell
// JSON can contain single quotes in string values,
// which would break echo 'JSON' shell command and allow potential code injection
resourcesStr := string(resourcesJson)
logger.Info("writing resources", "json", resourcesStr)
resourcesB64 := base64.StdEncoding.EncodeToString(resourcesJson)
stdout, stderr, err := executor.ExecNamed(ctx, "WriteResources", []string{"bash", "-ce", fmt.Sprintf(`
mkdir -p /opt/weka/k8s-runtime/tmp
echo '%s' > /opt/weka/k8s-runtime/tmp/resources.json
echo '%s' | base64 -d > /opt/weka/k8s-runtime/tmp/resources.json
mv /opt/weka/k8s-runtime/tmp/resources.json /opt/weka/k8s-runtime/resources.json
`, resourcesStr)})
`, resourcesB64)})
if err != nil {
logger.Error(err, "Error writing resources", "stderr", stderr.String(), "stdout", stdout.String())
return err
Expand Down
6 changes: 6 additions & 0 deletions internal/node_agent/node_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,12 @@ func (a *NodeAgent) getActiveMounts(w http.ResponseWriter, r *http.Request) {
}

if shouldCheckContainerSpecific {
// Validate containerName to prevent path traversal attacks
// Container names should only contain alphanumeric characters, hyphens, and underscores
if strings.Contains(containerName, "..") || strings.Contains(containerName, "/") || strings.Contains(containerName, "\\") {
http.Error(w, "invalid container name", http.StatusBadRequest)
return
}
filePath = fmt.Sprintf("/proc/wekafs/%s/interface", containerName)
} else {
// Feature flag not enabled, use default path
Expand Down
Loading