Add OpenConfig user provider - #513
Conversation
1227441 to
aa94822
Compare
Implement UserProvider for the OpenConfig provider, targeting the standard OpenConfig path: openconfig-system:system/aaa/authentication/users/user[username=X]/config Nokia SR Linux limitation: the OpenConfig user model on SRLinux does not expose password or ssh-public-key as writable config leaves — only username and role are settable, and only a single role is accepted. The provider raises UnsupportedFieldError for spec.password, spec.sshPublicKey, and spec.roles when more than one role is given. Since spec.password is mandatory in the CRD, User CRs will always reach Ready=False (terminal) on Nokia SRL via the OpenConfig provider. Also adds a gnmi testdata file documenting the expected device state for a user created with a single role. Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Robert Gildein <rgildein@users.noreply.github.com>
aa94822 to
f480dcc
Compare
…feat/openconfig-user
Rewrite the user provider to target vanilla OpenConfig rather than Nokia SRLinux-specific behavior: - Support password, ssh-key and role — all standard OpenConfig user config leaves (openconfig-system:system/aaa/authentication/users) - Use gNMI update (Patch) instead of replace (Update) for user creation — Juniper rejects replace for new entries with "statement not found" - Password excluded from UnmarshalJSON to avoid perpetual diffs (device returns hashed value that never matches plaintext) - Remove Nokia-specific UnsupportedFieldError for password/sshPublicKey - Remove CodeIgnoredField from apistatus — not needed for vanilla OpenConfig; revert related changes to conditions.go and user_controller.go - Only retain single-role constraint (OpenConfig role leaf is a single value, not a leaf-list — confirmed on both Juniper and Nokia) - Replace user.txt testdata with proper user.txtar including secrets and full expected gNMI state with ssh-key Tested against Juniper vJunos-Evolved 26.2R1.7 via containerlab. Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Robert Gildein <rgildein@users.noreply.github.com>
|
|
||
| // UserConfig holds the user config container leaves. | ||
| // Password is write-only — the device returns a hashed value that would never match | ||
| // the plaintext, so we exclude it from unmarshal to avoid perpetual diffs. |
There was a problem hiding this comment.
Please have a look into what we are doing on the nxos provider in https://github.com/ironcore-dev/network-operator/blob/main/internal/provider/cisco/nxos/provider.go#L2620-L2641
We take the plaintext password as we retrieve it from the kubernetes secret and compute the hash ourselves (which we can do if the hash includes the algorithm and salt value). If the hash we compute from the plaintext value matches, what is stored in hashed form on the device. We can retain that value.
Otherwise, we would end up with a gnmi write on every reconcilation, which we definitely want to avoid.
There was a problem hiding this comment.
Ok so if user set up password we hashed and set hashed password on device. Make sense, I'll check the mechanism how we are hashing it.
| // User targets an OpenConfig user entry. | ||
| type User struct { | ||
| Username string `json:"-"` | ||
| Config *UserConfig `json:"config,omitempty"` |
There was a problem hiding this comment.
| Config *UserConfig `json:"config,omitempty"` | |
| Config *UserConfig `json:"config"` |
This field is always present and should therefore not have an omitempty tag. See
Lines 156 to 161 in e21328d
| SSHKey: req.SSHKey, | ||
| }, | ||
| } | ||
| return p.client.Patch(ctx, u) |
There was a problem hiding this comment.
Any particular reason we use a patch over an update here?
There was a problem hiding this comment.
Update was failing on Juniper device, I think it was to avoid changing username <==> creating new user. I can try out with update and share the message if you want.
Use SHA-512 crypt ($6$) to hash the user password before setting it via the password-hashed field. Reuse the existing hash when the password matches to avoid unnecessary gNMI Set calls. Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Robert Gildein <rgildein@users.noreply.github.com>
|
@rgildein when merging this PR, could you make sure to squash the commits into a single one so we keep the history linear and clean? 🙏 |
Signed-off-by: Robert Gildein <rgildein@users.noreply.github.com>
99eb9b5 to
b2a61f0
Compare
Merging this branch will increase overall coverage
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
Add OpenConfig provider implementation for the
Userresource targeting the standard OpenConfig path:openconfig-system:system/aaa/authentication/users/user[username=X]/configWhat changed
Initial implementation:
EnsureUser/DeleteUserfor the OpenConfig providerusername,role, andssh-key— standard OpenConfig user config leavesPatch) instead of replace — Juniper rejects gNMI replace for new list entries withstatement not found; update works for both create and updatespec.roleswith more than one entry returnsUnsupportedFieldError— the OpenConfigroleleaf is a single value, confirmed on both Juniper and NokiaPassword hashing:
$6$) before being sent to the device via thepassword-hashedgNMI fieldpassword-hashedis stored verbatim by Juniper, enabling idempotent reconciliation: the existing hash is read back, its salt extracted, and the password re-hashed — if the password is unchanged the output is identical and no gNMI Set is issuedTesting
Validated against a real Juniper vJunos-Evolved device:
username,password,role, andssh-keyJuniper vJunos-Evolved
Device: Juniper vJunos-Evolved 26.2R1.7 via containerlab
Verify user config:
Nokia SR Linux
Nokia SRL's OpenConfig user model does not expose
passwordorssh-keyas writable leaves — onlyusernameandroleare supported via OpenConfig. A separate Nokia-specific provider will be needed for password and SSH key management.