Skip to content

allow update of ldap linked account - #13949

Merged
DaanHoogland merged 2 commits into
mainfrom
ghi11185-update-ldap-domain-on-account
Sep 9, 2026
Merged

DaanHoogland merged 2 commits into
mainfrom
ghi11185-update-ldap-domain-on-account

Conversation

@DaanHoogland

Copy link
Copy Markdown
Contributor

Description

This PR...

Fixes: #11185

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@codecov

codecov Bot commented Aug 22, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 19.74%. Comparing base (158fe4f) to head (012307c).
⚠️ Report is 37 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main   #13949   +/-   ##
=========================================
  Coverage     19.74%   19.74%           
- Complexity    19960    19976   +16     
=========================================
  Files          6371     6371           
  Lines        575784   575792    +8     
  Branches      70478    70479    +1     
=========================================
+ Hits         113665   113710   +45     
+ Misses       449765   449730   -35     
+ Partials      12354    12352    -2     
Flag Coverage Δ
uitests 3.41% <ø> (ø)
unittests 21.02% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Aug 22, 2026 •

Copy link
Copy Markdown

🔴 Test Coverage Grade: D — Marginal

Metric Value
Line coverage 24.62%
Branch coverage 18.82%

Grade Scale

Grade Line Coverage Meaning
🟢 A ≥ 80% Excellent - this code sleeps well at night 😴
🟡 B 60-79% Good - almost there, don't stop now 😉
🟠 C 40-59% Acceptable - your code is wearing a seatbelt, but no airbags 😬
🔴 D 20-39% Marginal - boldly shipping where no test has gone before 🖖
⛔ F < 20% Failing - tests? what tests? 🔥

Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run

@DaanHoogland
DaanHoogland force-pushed the ghi11185-update-ldap-domain-on-account branch from 4825b6d to cc543f0 Compare August 22, 2026 21:29
@DaanHoogland
DaanHoogland force-pushed the ghi11185-update-ldap-domain-on-account branch from 4ca51b7 to 012307c Compare August 25, 2026 19:13
@DaanHoogland

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 18984

@sonarqubecloud

Copy link
Copy Markdown

@DaanHoogland
DaanHoogland requested a review from shwstppr August 26, 2026 11:35
@DaanHoogland DaanHoogland added this to the 24.0.0 milestone Aug 26, 2026
@DaanHoogland
DaanHoogland requested a review from RosiKyu August 26, 2026 11:35
@DaanHoogland DaanHoogland moved this from Backlog to Ready in CloudStack Testing Sep 1, 2026
@DaanHoogland

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

blueorangutan commented Sep 2, 2026 •

Copy link
Copy Markdown

[SF] Trillian test result (tid-16859)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 56436 seconds
Marvin logs: [archive removed]
Smoke tests completed. 156 look OK, 0 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File

@kiranchavala kiranchavala left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Tested manually

cmk create account accounttype=0 username=qa-admin password=x email=a@b.c firstname=q lastname=a account=qa-team-acct domainid=7d685c93-0d65-4cbb-9afe-223d1000aa7d roleid=4

cmk link accounttoldap domainid=7d685c93-0d65-4cbb-9afe-223d1000aa7d account=qa-team-acct type=GROUP ldapdomain='cn=qa-team,ou=Telco-Bng,dc=example,dc=in' accounttype=0

mysql> SELECT id, domain_id, account_id, name, type FROM cloud.ldap_trust_map;
+----+-----------+------------+------------------------------------------+-------+
| id | domain_id | account_id | name                                     | type  |
+----+-----------+------------+------------------------------------------+-------+
|  3 |         2 |          8 | cn=qa-team,ou=Telco-Bng,dc=example,dc=in | GROUP |
+----+-----------+------------+------------------------------------------+-------+
1 row in set (0.00 sec)

Able to login with the user

update the link accounttoldap setting

cmk link accounttoldap domainid=7d685c93-0d65-4cbb-9afe-223d1000aa7d account=qa-team-acct type=GROUP ldapdomain='cn=dev-team,ou=Telco-Bng,dc=example,dc=in' accounttype=0

mysql> SELECT id, domain_id, account_id, name, type FROM cloud.ldap_trust_map;
+----+-----------+------------+-------------------------------------------+-------+
| id | domain_id | account_id | name                                      | type  |
+----+-----------+------------+-------------------------------------------+-------+
|  4 |         2 |          8 | cn=dev-team,ou=Telco-Bng,dc=example,dc=in | GROUP |
+----+-----------+------------+-------------------------------------------+-------+
1 row in set (0.00 sec)

Able to login with a new account

@shwstppr
shwstppr requested a lite review from Copilot September 9, 2026 10:31
@DaanHoogland
DaanHoogland merged commit 068d393 into main Sep 9, 2026
30 checks passed
@github-project-automation github-project-automation Bot moved this from Ready to Done in CloudStack Testing Sep 9, 2026
@vishesh92
vishesh92 deleted the ghi11185-update-ldap-domain-on-account branch September 9, 2026 10:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Enables updating an existing LDAP-linked account by making the link operation replace the account’s prior mapping (instead of failing on uniqueness constraints), and adds unit tests around relinking behavior.

Changes:

  • Wrap LDAP link update in a transaction and explicitly clear the account’s existing mapping before persisting the new one.
  • Adjust conflict checks so relinking to the same group doesn’t error, while still blocking groups claimed by other active accounts.
  • Add JUnit tests covering relinking, conflicts, removed accounts, and failure rollback behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapManagerImpl.java Make relinking atomic and allow replacing an account’s existing LDAP mapping; refine conflict detection.
plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/ldap/LdapManagerImplTest.java Add coverage for relinking scenarios and failure modes introduced/changed by the new behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +523 to +527
/**
* Replaces the account's existing LDAP mapping, if any, so {@link #linkAccountToLdap}
* can update the ldapDomain/type of an existing link instead of failing on the
* domain_id/account_id unique key.
*/
private void clearAccountsOwnMapping(Long domainId, long accountId) {
LdapTrustMapVO ownVo = _ldapTrustMapDao.findByAccount(domainId, accountId);
if (ownVo != null) {
logger.warn("account {} in domain {} is already linked to ldap {} '{}'; replacing with the new mapping", accountId, domainId, ownVo.getType(), ownVo.getName());
Comment on lines +478 to +482
LdapTrustMapVO vo = Transaction.execute((TransactionCallback<LdapTrustMapVO>) status -> {
clearOldAccountMapping(cmd, accountId);
clearAccountsOwnMapping(cmd.getDomainId(), accountId);
return _ldapTrustMapDao.persist(new LdapTrustMapVO(cmd.getDomainId(), linkType, cmd.getLdapDomain(), cmd.getAccountType(), accountId));
});
if (oldVo != null && oldVo.getAccountId() != accountId) {
// deal with edge cases, i.e. check if the old account is indeed deleted etc.
if (oldVo.getAccountId() != 0L) {
AccountVO oldAcount = accountDao.findByIdIncludingRemoved(oldVo.getAccountId());

private static final Long DOMAIN_ID = 1L;
private static final long ACCOUNT_ID = 24L;
private static final long OLD_MAPPING_ID = 5L;
Comment on lines +81 to +97
when(LdapConfiguration.getBaseDn(DOMAIN_ID)).thenReturn("dc=my,dc=domain,dc=com");

ldapManager = new LdapManagerImpl();
ldapManager._ldapTrustMapDao = ldapTrustMapDaoMock;
ReflectionTestUtils.setField(ldapManager, "domainDao", domainDaoMock);
ReflectionTestUtils.setField(ldapManager, "accountDao", accountDaoMock);
when(domainDaoMock.findById(DOMAIN_ID)).thenReturn(new DomainVO());

AccountVO existingAccount = new AccountVO("jdoe", DOMAIN_ID, null, Account.Type.NORMAL, null, "acct-uuid");
ReflectionTestUtils.setField(existingAccount, "id", ACCOUNT_ID);
when(accountDaoMock.findActiveAccount("jdoe", DOMAIN_ID)).thenReturn(existingAccount);
when(ldapTrustMapDaoMock.persist(any())).thenAnswer(invocation -> invocation.getArgument(0));
}

@After
public void tearDown() {
ldapConfigurationMockedStatic.close();
public void relinkingAccountAllowsGroupOnceOtherClaimingAccountIsRemoved() {
long removedAccountId = 99L;
LdapTrustMapVO otherMapping = new LdapTrustMapVO(DOMAIN_ID, LdapManager.LinkType.GROUP, "cn=stale,dc=my,dc=domain,dc=com", Account.Type.NORMAL, removedAccountId);
ReflectionTestUtils.setField(otherMapping, "id", OLD_MAPPING_ID);
@Test
public void relinkingAccountDoesNotPersistWhenClearingOldMappingFails() {
LdapTrustMapVO ownMapping = new LdapTrustMapVO(DOMAIN_ID, LdapManager.LinkType.GROUP, "cn=old,dc=my,dc=domain,dc=com", Account.Type.NORMAL, ACCOUNT_ID);
ReflectionTestUtils.setField(ownMapping, "id", OLD_MAPPING_ID);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

Link Account to LDAP Improvement - Update ldapdomain value

4 participants