QA_Handoff_SSO_Cutover_v2.0.0.md #1

  • //
  • guest/
  • tom_tyler/
  • sw/
  • main/
  • SSO_Cutover/
  • ai/
  • QA_Handoff_SSO_Cutover_v2.0.0.md
  • Markdown
  • View
  • Commits
  • Open Download .zip Download (9 KB)

QA Handoff: SSO_Cutover.sh v2.0.0 — -rollback Feature

Date: 2026-04-08
Author: Claude (Sonnet 4.6), acting on behalf of Tom Tyler
Status: Ready for QA
P4 Location: //guest/tom_tyler/sw/main/SSO_Cutover/


Background

SSO_Cutover.sh is a production script that migrates a Perforce server's human users from LDAP-managed authentication to the Perforce Authentication Service (P4AS), enabling Single Sign-On (SSO). The script was built, tested, and verified by the customer in a copy-of-production sandbox at v1.1.4.

After that acceptance test, the customer requested a rollback capability — a way to reverse all cutover changes in an emergency without manually editing ~1000 user records. This is the feature added in v2.0.0.


What Changed in v2.0.0

A new -rollback option was added to SSO_Cutover.sh. It reverses, in a single command, everything the forward cutover run changed — but only what it actually changed.

How tracking works

During a live (-y) forward run, the script now records what it did using p4 key entries:

Key Meaning
SSO_Cutover.chg.auth.sso.allow.passwd Phase 1 set this configurable
SSO_Cutover.chg.auth.sso.nonldap Phase 1 set this configurable
SSO_Cutover.chg.auth.default.method Phase 1 set this configurable
SSO_Cutover.chg.extension Phase 2 updated the P4AS extension
SSO_Cutover.chg.trigger Phase 3 added the SSO_default trigger
SSO_Cutover.ldap.0.<username> Phase 4 changed this user's AuthMethod from ldap→perforce

Phase 2 also saves the original extension config to a file: $LOGS/SSO_Cutover.extension_backup.p4s

What rollback reverses

Rollback Phase Action
Phase 1 configure unset for each changed configurable; reverts auth.default.method to ldap
Phase 2 Restores the P4AS extension from the backup file
Phase 3 Removes SSO_default entries from the Triggers table
Phase 4 Sets AuthMethod=ldap for each user tracked by a SSO_Cutover.ldap.0.* key

After a successful live rollback, all tracking keys are deleted (clean slate).

Rollback constraints (enforced by the script)

  • -rollback requires -y to actually do anything (dry run by default, same as forward run)
  • -g is not allowed with -rollback (group is not needed; user set comes from keys)
  • -nc, -ne, -nt, -nu are not allowed with -rollback (rollback is automatic)
  • Passwords set during the forward run cannot be restored — this is acceptable for this customer because human users authenticate via LDAP and are unaffected by the P4 database password

Proposed Test Environment

Use a P4 Battle School Workshop training lab instance. These labs have a realistic training data set that can be adapted for this purpose.

Required data setup (simulate pre-cutover state)

The lab needs to be in the state the script expects to find at the start of a forward run:

  1. P4AS Extension installed in opt-in mode
    The extension (Auth::loginhook, name loginhook-a1) must exist and be configured with a small set of SSO opt-in users/groups (simulating the pilot phase). The rollback will need to restore this opt-in config, so it must exist and be saved as the baseline.

  2. Configurables at pre-SSO values

    • auth.sso.allow.passwd — should be 0 or unset
    • auth.sso.nonldap — should be 0 or unset
    • auth.default.method — should be ldap
  3. SSO_default trigger absent
    The SSO_default trigger should not yet be in the Triggers table.

  4. A mix of user AuthMethod values

    • Most users: AuthMethod: ldap (these should be changed by forward run and restored by rollback)
    • A handful: AuthMethod: perforce already (the simulated pilot/opt-in users — these should be left alone by rollback since SSO_Cutover.ldap.0.<user> won't be set for them)
  5. A Non-SSO exempt group
    Create a group (e.g. Non-SSO) containing at least the perforce super user and any simulated automation/robot accounts.

  6. SDP layout
    The script sources /p4/common/bin/p4_vars. The lab must have a working SDP layout, or the relevant variables (P4BIN, LOGS, P4TMP, etc.) must be set in the environment. $LOGS must be a writable directory — this is where the extension backup file lands.


Test Plan

Run all tests first as a dry run (no -y) to verify the preview output looks correct, then repeat as a live run (-y) to verify actual changes.

Test 1 — Happy path: forward run

SSO_Cutover.sh -g Non-SSO -y

Verify after:

  • p4 configure show auth.sso.allow.passwd → 1
  • p4 configure show auth.sso.nonldap → 1
  • p4 configure show auth.default.method → perforce
  • p4 extension --configure Auth::loginhook --name loginhook-a1 -o → opt-out mode (non-sso-groups: Non-SSO, non-sso-users: perforce, sso-groups/sso-users: none)
  • p4 triggers -o → SSO_default entries present
  • p4 -ztag -F "%User% %AuthMethod%" users → all non-exempt users show perforce
  • p4 keys -e "SSO_Cutover.*" → tracking keys present
  • $LOGS/SSO_Cutover.extension_backup.p4s → file exists and contains valid opt-in config

Test 2 — Happy path: rollback dry run

SSO_Cutover.sh -rollback

Verify:

  • Output describes what would be reversed with NO_OP: prefixes
  • No actual changes made (configurables, extension, triggers, users all unchanged)
  • Tracking keys still present

Test 3 — Happy path: rollback live run

SSO_Cutover.sh -rollback -y

Verify after:

  • p4 configure show auth.sso.allow.passwd → 0 or unset (original state)
  • p4 configure show auth.sso.nonldap → 0 or unset
  • p4 configure show auth.default.method → ldap
  • Extension back in opt-in mode (diff against original opt-in config)
  • p4 triggers -o → SSO_default entries gone
  • Users whose AuthMethod was changed → back to ldap
  • Users already on perforce before the forward run → still perforce (untouched)
  • p4 keys -e "SSO_Cutover.*" → all tracking keys deleted

Test 4 — Idempotency: double rollback

Run rollback a second time immediately after Test 3.

Verify:

  • Script runs without errors
  • Output says each phase has nothing to undo ("was not changed by the SSO cutover; skipping")
  • Exit code 0

Test 5 — Partial forward run (phase skipped)

Run forward with -ne (skip extension processing):

SSO_Cutover.sh -g Non-SSO -ne -y

Then run rollback:

SSO_Cutover.sh -rollback -y

Verify:

  • Rollback Phase 2 reports "P4AS extension was not changed by the SSO cutover; skipping"
  • Extension is NOT touched by rollback
  • Configurables, triggers, and users are properly rolled back

Test 6 — Invalid option combinations (should all fail with usage errors)

SSO_Cutover.sh -rollback -g Non-SSO       # -g not allowed with -rollback
SSO_Cutover.sh -rollback -nc              # phase-skip not allowed with -rollback
SSO_Cutover.sh -rollback -ne
SSO_Cutover.sh -rollback -nt
SSO_Cutover.sh -rollback -nu

Verify: Each prints a usage error and exits with code 2.

Test 7 — Rollback with no prior forward run

Attempt rollback on a clean instance with no SSO_Cutover.* keys:

SSO_Cutover.sh -rollback -y

Verify:

  • Script runs without errors
  • All phases report "was not changed by the SSO cutover; skipping"
  • Exit code 0

Test 8 — Missing extension backup file

After a forward run, delete the extension backup file, then attempt rollback:

rm "$LOGS/SSO_Cutover.extension_backup.p4s"
SSO_Cutover.sh -rollback -y

Verify:

  • Rollback Phase 2 reports an error: "Extension backup file not found"
  • Other phases (1, 3, 4) still complete successfully
  • Exit code reflects 1 error

Files

File Description
SSO_Cutover.sh The script (v2.0.0)
SSO_Cutover.command_summary.txt Output of SSO_Cutover.sh -man; regenerated for v2.0.0
TestUtility-ResetToBaseline.sh Pre-existing reset utility (lab only); does not have the rollback precision of the new -rollback option

Notes for the Testing Agent

  • The script requires an SDP environment. Key variables sourced from p4_vars: P4BIN, P4USER, LOGS, P4TMP.
  • ShellCheck passes cleanly on the v2.0.0 script.
  • The forward-run tracking keys use NoOp=0 (i.e., SSO_Cutover.0.<user> and SSO_Cutover.ldap.0.<user>). Dry-run keys (SSO_Cutover.1.*) are also cleaned up by rollback but don't gate any rollback logic.
  • The existing TestUtility-ResetToBaseline.sh can be used between test iterations to reset lab state, but note it resets all users (not just those tracked by the script) and requires the BASELINE.extension.p4s file to exist. It is complementary to, not a replacement for, the new -rollback option.
  • After each live rollback test, re-run the forward cutover to restore SSO state before the next rollback test.
# QA Handoff: SSO_Cutover.sh v2.0.0 — `-rollback` Feature

**Date:** 2026-04-08  
**Author:** Claude (Sonnet 4.6), acting on behalf of Tom Tyler  
**Status:** Ready for QA  
**P4 Location:** `//guest/tom_tyler/sw/main/SSO_Cutover/`

---

## Background

`SSO_Cutover.sh` is a production script that migrates a Perforce server's human users from
LDAP-managed authentication to the Perforce Authentication Service (P4AS), enabling Single
Sign-On (SSO). The script was built, tested, and verified by the customer in a
copy-of-production sandbox at v1.1.4.

After that acceptance test, the customer requested a rollback capability — a way to reverse
all cutover changes in an emergency without manually editing ~1000 user records. This is the
feature added in v2.0.0.

---

## What Changed in v2.0.0

A new `-rollback` option was added to `SSO_Cutover.sh`. It reverses, in a single command,
everything the forward cutover run changed — but only what it actually changed.

### How tracking works

During a **live** (`-y`) forward run, the script now records what it did using `p4 key`
entries:

| Key | Meaning |
|-----|---------|
| `SSO_Cutover.chg.auth.sso.allow.passwd` | Phase 1 set this configurable |
| `SSO_Cutover.chg.auth.sso.nonldap` | Phase 1 set this configurable |
| `SSO_Cutover.chg.auth.default.method` | Phase 1 set this configurable |
| `SSO_Cutover.chg.extension` | Phase 2 updated the P4AS extension |
| `SSO_Cutover.chg.trigger` | Phase 3 added the SSO_default trigger |
| `SSO_Cutover.ldap.0.<username>` | Phase 4 changed this user's AuthMethod from ldap→perforce |

Phase 2 also saves the original extension config to a file:
`$LOGS/SSO_Cutover.extension_backup.p4s`

### What rollback reverses

| Rollback Phase | Action |
|----------------|--------|
| Phase 1 | `configure unset` for each changed configurable; reverts `auth.default.method` to `ldap` |
| Phase 2 | Restores the P4AS extension from the backup file |
| Phase 3 | Removes `SSO_default` entries from the Triggers table |
| Phase 4 | Sets `AuthMethod=ldap` for each user tracked by a `SSO_Cutover.ldap.0.*` key |

After a successful live rollback, all tracking keys are deleted (clean slate).

### Rollback constraints (enforced by the script)

- `-rollback` **requires** `-y` to actually do anything (dry run by default, same as forward run)
- `-g` is **not allowed** with `-rollback` (group is not needed; user set comes from keys)
- `-nc`, `-ne`, `-nt`, `-nu` are **not allowed** with `-rollback` (rollback is automatic)
- Passwords set during the forward run **cannot** be restored — this is acceptable for this
  customer because human users authenticate via LDAP and are unaffected by the P4 database
  password

---

## Proposed Test Environment

Use a **P4 Battle School Workshop** training lab instance. These labs have a realistic training
data set that can be adapted for this purpose.

### Required data setup (simulate pre-cutover state)

The lab needs to be in the state the script expects to find at the *start* of a forward run:

1. **P4AS Extension installed** in opt-in mode  
   The extension (`Auth::loginhook`, name `loginhook-a1`) must exist and be configured with
   a small set of SSO opt-in users/groups (simulating the pilot phase). The rollback will
   need to restore this opt-in config, so it must exist and be saved as the baseline.

2. **Configurables at pre-SSO values**  
   - `auth.sso.allow.passwd` — should be `0` or unset  
   - `auth.sso.nonldap` — should be `0` or unset  
   - `auth.default.method` — should be `ldap`

3. **SSO_default trigger absent**  
   The `SSO_default` trigger should not yet be in the Triggers table.

4. **A mix of user AuthMethod values**  
   - Most users: `AuthMethod: ldap` (these should be changed by forward run and restored
     by rollback)
   - A handful: `AuthMethod: perforce` already (the simulated pilot/opt-in users — these
     should be left alone by rollback since `SSO_Cutover.ldap.0.<user>` won't be set
     for them)

5. **A Non-SSO exempt group**  
   Create a group (e.g. `Non-SSO`) containing at least the `perforce` super user and any
   simulated automation/robot accounts.

6. **SDP layout**  
   The script sources `/p4/common/bin/p4_vars`. The lab must have a working SDP layout,
   or the relevant variables (`P4BIN`, `LOGS`, `P4TMP`, etc.) must be set in the
   environment. `$LOGS` must be a writable directory — this is where the extension backup
   file lands.

---

## Test Plan

Run all tests first as a **dry run** (no `-y`) to verify the preview output looks correct,
then repeat as a **live run** (`-y`) to verify actual changes.

### Test 1 — Happy path: forward run

```bash
SSO_Cutover.sh -g Non-SSO -y
```

**Verify after:**
- `p4 configure show auth.sso.allow.passwd` → `1`
- `p4 configure show auth.sso.nonldap` → `1`
- `p4 configure show auth.default.method` → `perforce`
- `p4 extension --configure Auth::loginhook --name loginhook-a1 -o` → opt-out mode
  (non-sso-groups: Non-SSO, non-sso-users: perforce, sso-groups/sso-users: none)
- `p4 triggers -o` → `SSO_default` entries present
- `p4 -ztag -F "%User% %AuthMethod%" users` → all non-exempt users show `perforce`
- `p4 keys -e "SSO_Cutover.*"` → tracking keys present
- `$LOGS/SSO_Cutover.extension_backup.p4s` → file exists and contains valid opt-in config

### Test 2 — Happy path: rollback dry run

```bash
SSO_Cutover.sh -rollback
```

**Verify:**
- Output describes what would be reversed with `NO_OP:` prefixes
- No actual changes made (configurables, extension, triggers, users all unchanged)
- Tracking keys still present

### Test 3 — Happy path: rollback live run

```bash
SSO_Cutover.sh -rollback -y
```

**Verify after:**
- `p4 configure show auth.sso.allow.passwd` → `0` or unset (original state)
- `p4 configure show auth.sso.nonldap` → `0` or unset
- `p4 configure show auth.default.method` → `ldap`
- Extension back in opt-in mode (diff against original opt-in config)
- `p4 triggers -o` → `SSO_default` entries gone
- Users whose AuthMethod was changed → back to `ldap`
- Users already on `perforce` before the forward run → still `perforce` (untouched)
- `p4 keys -e "SSO_Cutover.*"` → all tracking keys deleted

### Test 4 — Idempotency: double rollback

Run rollback a second time immediately after Test 3.

**Verify:**
- Script runs without errors
- Output says each phase has nothing to undo ("was not changed by the SSO cutover; skipping")
- Exit code 0

### Test 5 — Partial forward run (phase skipped)

Run forward with `-ne` (skip extension processing):

```bash
SSO_Cutover.sh -g Non-SSO -ne -y
```

Then run rollback:

```bash
SSO_Cutover.sh -rollback -y
```

**Verify:**
- Rollback Phase 2 reports "P4AS extension was not changed by the SSO cutover; skipping"
- Extension is NOT touched by rollback
- Configurables, triggers, and users are properly rolled back

### Test 6 — Invalid option combinations (should all fail with usage errors)

```bash
SSO_Cutover.sh -rollback -g Non-SSO       # -g not allowed with -rollback
SSO_Cutover.sh -rollback -nc              # phase-skip not allowed with -rollback
SSO_Cutover.sh -rollback -ne
SSO_Cutover.sh -rollback -nt
SSO_Cutover.sh -rollback -nu
```

**Verify:** Each prints a usage error and exits with code 2.

### Test 7 — Rollback with no prior forward run

Attempt rollback on a clean instance with no `SSO_Cutover.*` keys:

```bash
SSO_Cutover.sh -rollback -y
```

**Verify:**
- Script runs without errors
- All phases report "was not changed by the SSO cutover; skipping"
- Exit code 0

### Test 8 — Missing extension backup file

After a forward run, delete the extension backup file, then attempt rollback:

```bash
rm "$LOGS/SSO_Cutover.extension_backup.p4s"
SSO_Cutover.sh -rollback -y
```

**Verify:**
- Rollback Phase 2 reports an error: "Extension backup file not found"
- Other phases (1, 3, 4) still complete successfully
- Exit code reflects 1 error

---

## Files

| File | Description |
|------|-------------|
| `SSO_Cutover.sh` | The script (v2.0.0) |
| `SSO_Cutover.command_summary.txt` | Output of `SSO_Cutover.sh -man`; regenerated for v2.0.0 |
| `TestUtility-ResetToBaseline.sh` | Pre-existing reset utility (lab only); does not have the rollback precision of the new `-rollback` option |

---

## Notes for the Testing Agent

- The script requires an SDP environment. Key variables sourced from `p4_vars`:
  `P4BIN`, `P4USER`, `LOGS`, `P4TMP`.
- ShellCheck passes cleanly on the v2.0.0 script.
- The forward-run tracking keys use `NoOp=0` (i.e., `SSO_Cutover.0.<user>` and
  `SSO_Cutover.ldap.0.<user>`). Dry-run keys (`SSO_Cutover.1.*`) are also cleaned
  up by rollback but don't gate any rollback logic.
- The existing `TestUtility-ResetToBaseline.sh` can be used between test iterations to
  reset lab state, but note it resets *all* users (not just those tracked by the script)
  and requires the `BASELINE.extension.p4s` file to exist. It is complementary to, not
  a replacement for, the new `-rollback` option.
- After each live rollback test, re-run the forward cutover to restore SSO state before
  the next rollback test.
# Change User Description Committed
#1 32545 C. Thomas Tyler Add QA handoff notes for SSO_Cutover.sh v2.0.0 -rollback feature