From 4427ef0cfc2979ab45f48620ffb926be356a86ea Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 15 Sep 2025 12:45:36 +0200 Subject: [PATCH] CKS: generate a strong random password for CKS user --- api/src/main/java/com/cloud/user/User.java | 2 +- .../cluster/KubernetesClusterManagerImpl.java | 20 +++++++++++++++---- .../com/cloud/user/AccountManagerImpl.java | 4 +++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/cloud/user/User.java b/api/src/main/java/com/cloud/user/User.java index 041b39ad2729..8ccaa9212fe9 100644 --- a/api/src/main/java/com/cloud/user/User.java +++ b/api/src/main/java/com/cloud/user/User.java @@ -24,7 +24,7 @@ public interface User extends OwnedBy, InternalIdentity { // UNKNOWN and NATIVE can be used interchangeably public enum Source { - OAUTH2, LDAP, SAML2, SAML2DISABLED, UNKNOWN, NATIVE + OAUTH2, LDAP, SAML2, SAML2DISABLED, UNKNOWN, NATIVE, CKS } public static final long UID_SYSTEM = 1; diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java index 9b3e487680d4..214dee3aaf69 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java @@ -41,7 +41,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.user.PasswordPolicy; import com.cloud.uservm.UserVm; +import com.cloud.utils.PasswordGenerator; import com.cloud.vm.UserVmService; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.Role; @@ -242,6 +244,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne ); private static final String PROJECT_KUBERNETES_ACCOUNT_FIRST_NAME = "Kubernetes"; private static final String PROJECT_KUBERNETES_ACCOUNT_LAST_NAME = "Service User"; + private static final int CKS_USER_MIN_PASSWORD_LENGTH = 12; private static final String DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering used for CloudStack Kubernetes service"; @@ -1499,6 +1502,14 @@ protected String[] createUserApiKeyAndSecretKey(long userId) { } } + protected String generateRandomUserPassword(Long domainId) { + Integer passwordPolicyMinimumLength = PasswordPolicy.PasswordPolicyMinimumLength.valueIn(domainId); + if (passwordPolicyMinimumLength == null || passwordPolicyMinimumLength < CKS_USER_MIN_PASSWORD_LENGTH) { + passwordPolicyMinimumLength = CKS_USER_MIN_PASSWORD_LENGTH; + } + return PasswordGenerator.generateRandomPassword(passwordPolicyMinimumLength); + } + protected String[] getServiceUserKeys(Account owner) { String username = owner.getAccountName(); if (!username.startsWith(KUBEADMIN_ACCOUNT_NAME + "-")) { @@ -1507,8 +1518,9 @@ protected String[] getServiceUserKeys(Account owner) { UserAccount kubeadmin = accountService.getActiveUserAccount(username, owner.getDomainId()); String[] keys; if (kubeadmin == null) { - User kube = userDao.persist(new UserVO(owner.getAccountId(), username, UUID.randomUUID().toString(), owner.getAccountName(), - KUBEADMIN_ACCOUNT_NAME, "kubeadmin", null, UUID.randomUUID().toString(), User.Source.UNKNOWN)); + Integer passwordPolicyMinimumLength = PasswordPolicy.PasswordPolicyMinimumLength.valueIn(owner.getDomainId()); + User kube = userDao.persist(new UserVO(owner.getAccountId(), username, generateRandomUserPassword(owner.getDomainId()), owner.getAccountName(), + KUBEADMIN_ACCOUNT_NAME, "kubeadmin", null, UUID.randomUUID().toString(), User.Source.CKS)); keys = createUserApiKeyAndSecretKey(kube.getId()); } else { String apiKey = kubeadmin.getApiKey(); @@ -1551,9 +1563,9 @@ protected Account createProjectKubernetesAccount(final Project project, final St try { Role role = getProjectKubernetesAccountRole(); UserAccount userAccount = accountService.createUserAccount(accountName, - UuidUtils.first(UUID.randomUUID().toString()), PROJECT_KUBERNETES_ACCOUNT_FIRST_NAME, + generateRandomUserPassword(project.getDomainId()), PROJECT_KUBERNETES_ACCOUNT_FIRST_NAME, PROJECT_KUBERNETES_ACCOUNT_LAST_NAME, null, null, accountName, Account.Type.NORMAL, role.getId(), - project.getDomainId(), null, null, null, null, User.Source.NATIVE); + project.getDomainId(), null, null, null, null, User.Source.CKS); projectManager.assignAccountToProject(project, userAccount.getAccountId(), ProjectAccount.Role.Regular, userAccount.getId(), null); Account account = accountService.getAccount(userAccount.getAccountId()); diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index 04a64fbfc8c9..87791e95c7ce 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -2747,7 +2747,9 @@ protected UserVO createUser(long accountId, String userName, String password, St logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); } - passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(password, userName, getAccount(accountId).getDomainId()); + if (!User.Source.CKS.equals(source)) { + passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(password, userName, getAccount(accountId).getDomainId()); + } String encodedPassword = null; for (UserAuthenticator authenticator : _userPasswordEncoders) {