Skip to content

Add Defensive Mode to VIP-CLI#2756

Open
Crixu wants to merge 12 commits intotrunkfrom
add/defensive-mode-cli-commands
Open

Add Defensive Mode to VIP-CLI#2756
Crixu wants to merge 12 commits intotrunkfrom
add/defensive-mode-cli-commands

Conversation

@Crixu
Copy link

@Crixu Crixu commented Mar 4, 2026

Description

This PR adds CLI commands for managing Defensive Mode (bot/DDoS protection) on VIP environments. Customers can now automate defensive mode operations via vip-cli instead of manually managing each environment through the Dashboard.

Commands Added

  • vip @app.env defensive-mode enable - Enable bot/DDoS protection
  • vip @app.env defensive-mode disable - Disable protection (with confirmation)
  • vip @app.env defensive-mode status - View current configuration

Implementation Details

API Integration: Uses GraphQL API (not REST) via existing VIP-CLI patterns

  • Query: app.environments.defensiveMode for status
  • Mutations: updateDefensiveModeStatus for enable/disable

Security Features:

  • Interactive confirmation required for disable (destructive operation)
  • --confirm flag for automation (non-interactive mode)
  • Permission checks enforced by API (Org Admin or App Admin required)
  • All operations tracked via analytics events

Changelog Description

Added

  • Added vip defensive-mode enable command to enable bot and DDoS protection for an environment
  • Added vip defensive-mode disable command to disable bot and DDoS protection with confirmation prompt
  • Added vip defensive-mode status command to view current Defensive Mode configuration and state

Pull Request Checklist


New Release Checklist


Steps to Test

Prerequisites

  • Access to VIP app with Defensive Mode available
  • Org Admin or App Admin role

Test Enable Command

  1. Check out PR and build:

    git checkout add/defensive-mode-cli-commands
    npm run build
  2. Check initial status (should show current state):

    ./dist/bin/vip.js @your-app.production defensive-mode status
  3. Enable defensive mode:

    ./dist/bin/vip.js @your-app.production defensive-mode enable
  4. Verify:

    • Success message displays
    • Status shows "ACTIVE"
    • Configuration details displayed (threshold, challenge type, etc.)
    • Dashboard shows defensive mode enabled

Test Disable Command (Interactive)

  1. Disable with confirmation prompt:

    ./dist/bin/vip.js @your-app.production defensive-mode disable
  2. Verify:

    • Warning message displays with app/env name and domain
    • Prompt requires typing "DISABLE"
    • After confirmation, status shows "INACTIVE"
    • Dashboard shows defensive mode disabled
  3. Test cancellation:

    ./dist/bin/vip.js @your-app.production defensive-mode disable
    • Type anything other than "DISABLE"
    • Verify operation cancelled, defensive mode still disabled

Test Disable Command (Non-Interactive)

  1. Re-enable first:

    ./dist/bin/vip.js @your-app.production defensive-mode enable
  2. Disable with --confirm flag:

    ./dist/bin/vip.js @your-app.production defensive-mode disable --confirm
  3. Verify:

    • No prompt shown
    • Defensive mode disabled immediately
    • Success message displays

Test JSON Output

  1. Enable with JSON output:

    ./dist/bin/vip.js @your-app.production defensive-mode enable --format=json
  2. Verify:

    • Valid JSON output
    • Contains data.effective and data.stored objects
    • No human-readable text mixed in

Test Status Display

  1. Check status on WordPress site:

    ./dist/bin/vip.js @wordpress-app.production defensive-mode status
    • Verify shows "X% PHP workers" (percentage threshold)
  2. Check status on Node.js site (if available):

    ./dist/bin/vip.js @nodejs-app.production defensive-mode status
    • Verify shows "X concurrent requests" (absolute threshold)

Test Error Handling

  1. Test with insufficient permissions (if possible):

    • Use account with App Write or lower role
    • Verify clear error message about required role
  2. Test with invalid app:

    ./dist/bin/vip.js @nonexistent-app.production defensive-mode status
    • Verify appropriate error message

Verify Tests

npm test -- --testPathPatterns=defensive-mode

Expected: 24 tests passing

Crixu added 7 commits March 3, 2026 15:40
Implements defensive-mode subcommands for VIP-CLI:
- vip @app.env defensive-mode enable: Enable bot/DDoS protection
- vip @app.env defensive-mode disable: Disable protection with confirmation
- vip @app.env defensive-mode status: Display current config and status

Features:
- REST API integration via existing http client
- JSON output format for automation (--format=json)
- Interactive confirmation prompt for disable (--confirm to skip)
- Permission-aware error messages
- Analytics tracking via trackEvent
- Follows existing VIP-CLI patterns and conventions

Related: VIP CLI-Dashboard Parity Initiative (24 feature gaps identified)
Tests cover:
- Enable command: success cases, JSON output, already enabled state, error handling
- Disable command: confirmation prompt, --confirm flag, cancellation, error handling
- Status command: active/inactive states, WordPress/Node.js thresholds, custom vs default values, JSON output

All 24 tests passing:
- 8 enable command tests
- 8 disable command tests
- 8 status command tests

Includes proper mocking of API, exit, tracker, and prompt modules.
Test Plan (test-plan-defensive-mode.md):
- 20 comprehensive test cases
- Prerequisites and environment setup
- Manual validation procedures
- Dashboard verification steps
- Bulk operations testing
- Sign-off checklist

User Documentation (docs/defensive-mode.md):
- Complete CLI reference for all 3 commands
- Configuration field explanations
- Bulk operations examples
- CI/CD integration examples
- Best practices and troubleshooting
- Error message reference
- Permission requirements

Addresses steps 3 (staging validation) and 4 (documentation).
Add defensive-mode to command registry in vip.js to make it accessible via:
vip @app.env defensive-mode <subcommand>

Placed alphabetically between 'db' and 'dev-env' commands.
Issue: REST endpoints (/v1/sites/:siteId/defensive-mode) return 404
Cause: REST API not deployed to production Parker yet

Solution: Use GraphQL queries/mutations instead (what Dashboard uses)

Changes:
- getDefensiveMode: Uses GraphQL query or appQuery data
- updateDefensiveMode: Uses GraphQL mutation
- Expanded appQuery to include defensiveMode.config fields
- Fixed status display: correct env name, show only active threshold
- Tested successfully on vip-lucas-radke production (6633)

Result: All commands now working against production API ✅
- Use updateDefensiveModeStatus mutation for enable/disable (not updateDefensiveModeConfig)
- Query for updated config after mutation (mutation only returns success/message)
- Fix environment name display in all commands (use type instead of name)
- Fix threshold display to only show non-null value (percentage OR absolute, not both)

Tested successfully:
- Disable: vip-lucas-radke production -> INACTIVE ✅
- Enable: vip-lucas-radke production -> ACTIVE ✅
- Status: Shows correct config with proper formatting ✅

All 3 commands working end-to-end on production.
Purpose and Context:
Fixed TypeScript linting errors related to unsafe 'any' type access
on GraphQL responses. Added proper type definitions for all API
responses and parameters.

Key Changes:
- Added DefensiveModeGraphQLConfig interface
- Added UpdateDefensiveModeConfigResponse interface
- Added UpdateDefensiveModeStatusResponse interface
- Added DefensiveModeQueryResponse interface
- Added EnvironmentData interface for envData parameter
- Added type parameters to api.query() and api.mutate() calls
- Added null checks for message.includes() calls

Impact and Considerations:
Improves type safety and IDE autocomplete support. No runtime
behavior changes. Reduces linting errors from 31 to 4 (warnings only).

Testing and Validation:
- Build successful
- All 24 tests still passing
- Linting errors resolved (0 errors, 4 warnings)
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Crixu and others added 5 commits March 4, 2026 07:06
- Update test to expect third parameter (envData) in getDefensiveMode call
- Fix Prettier formatting in docs/defensive-mode.md

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Prefix unused parameters with underscore to comply with no-unused-vars rule

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove redundant error message fallbacks that confused static analysis

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove redundant null checks (numbers can't be null in TypeScript)
- Extract common status update logic to reduce duplication from 16.8% to <3%
- Simplify enable/disable to use shared helper function

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 4, 2026

@Crixu Crixu requested a review from a team March 4, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant