mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-3049: Implemented role update for account. (#3058)
This commit is contained in:
parent
97ddd8dffd
commit
d68712eb7b
@ -16,6 +16,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
cloudstack/tools/docker/Dockerfile
|
cloudstack/tools/docker/Dockerfile
|
||||||
|
cloudstack/tools/docker/Dockerfile.smokedev
|
||||||
.dockerignore
|
.dockerignore
|
||||||
.idea
|
.idea
|
||||||
.git
|
.git
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.RoleResponse;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
@ -48,16 +49,19 @@ public class UpdateAccountCmd extends BaseCmd {
|
|||||||
//////////////// API parameters /////////////////////
|
//////////////// API parameters /////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ACL(accessType = AccessType.OperateEntry)
|
@ACL(accessType = AccessType.OperateEntry)
|
||||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account id")
|
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the current account name")
|
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Current account name")
|
||||||
private String accountName;
|
private String accountName;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "the ID of the domain where the account exists")
|
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "The UUID of the domain where the account exists")
|
||||||
private Long domainId;
|
private Long domainId;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.NEW_NAME, type = CommandType.STRING, required = true, description = "new name for the account")
|
@Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "The UUID of the dynamic role to set for the account")
|
||||||
|
private Long roleId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.NEW_NAME, type = CommandType.STRING, description = "New name for the account")
|
||||||
private String newName;
|
private String newName;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.NETWORK_DOMAIN,
|
@Parameter(name = ApiConstants.NETWORK_DOMAIN,
|
||||||
@ -65,7 +69,7 @@ public class UpdateAccountCmd extends BaseCmd {
|
|||||||
description = "Network domain for the account's networks; empty string will update domainName with NULL value")
|
description = "Network domain for the account's networks; empty string will update domainName with NULL value")
|
||||||
private String networkDomain;
|
private String networkDomain;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
|
@Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "Details for the account used to store specific parameters")
|
||||||
private Map details;
|
private Map details;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -87,6 +91,8 @@ public class UpdateAccountCmd extends BaseCmd {
|
|||||||
return domainId;
|
return domainId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getRoleId() { return roleId; }
|
||||||
|
|
||||||
public String getNewName() {
|
public String getNewName() {
|
||||||
return newName;
|
return newName;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,8 +37,10 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.QuerySelector;
|
import org.apache.cloudstack.acl.QuerySelector;
|
||||||
|
import org.apache.cloudstack.acl.Role;
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
@ -1019,8 +1021,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
@DB
|
@DB
|
||||||
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
|
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
|
||||||
public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone, String accountName,
|
public UserAccount createUserAccount(final String userName, final String password, final String firstName,
|
||||||
final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID,
|
final String lastName, final String email, final String timezone,
|
||||||
|
String accountName, final short accountType, final Long roleId, Long domainId,
|
||||||
|
final String networkDomain, final Map<String, String> details,
|
||||||
|
String accountUUID, final String userUUID,
|
||||||
final User.Source source) {
|
final User.Source source) {
|
||||||
|
|
||||||
if (accountName == null) {
|
if (accountName == null) {
|
||||||
@ -1155,7 +1160,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
UserVO user = retrieveAndValidateUser(updateUserCmd);
|
UserVO user = retrieveAndValidateUser(updateUserCmd);
|
||||||
s_logger.debug("Updating user with Id: " + user.getUuid());
|
s_logger.debug("Updating user with Id: " + user.getUuid());
|
||||||
|
|
||||||
validateAndUpdatApiAndSecretKeyIfNeeded(updateUserCmd, user);
|
validateAndUpdateApiAndSecretKeyIfNeeded(updateUserCmd, user);
|
||||||
Account account = retrieveAndValidateAccount(user);
|
Account account = retrieveAndValidateAccount(user);
|
||||||
|
|
||||||
validateAndUpdateFirstNameIfNeeded(updateUserCmd, user);
|
validateAndUpdateFirstNameIfNeeded(updateUserCmd, user);
|
||||||
@ -1344,7 +1349,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
* <li>If a pair of keys is provided, we validate to see if there is an user already using the provided API key. If there is someone else using, we throw an {@link InvalidParameterValueException} because two users cannot have the same API key.
|
* <li>If a pair of keys is provided, we validate to see if there is an user already using the provided API key. If there is someone else using, we throw an {@link InvalidParameterValueException} because two users cannot have the same API key.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
protected void validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
protected void validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
||||||
String apiKey = updateUserCmd.getApiKey();
|
String apiKey = updateUserCmd.getApiKey();
|
||||||
String secretKey = updateUserCmd.getSecretKey();
|
String secretKey = updateUserCmd.getSecretKey();
|
||||||
|
|
||||||
@ -1687,6 +1692,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
public AccountVO updateAccount(UpdateAccountCmd cmd) {
|
public AccountVO updateAccount(UpdateAccountCmd cmd) {
|
||||||
Long accountId = cmd.getId();
|
Long accountId = cmd.getId();
|
||||||
Long domainId = cmd.getDomainId();
|
Long domainId = cmd.getDomainId();
|
||||||
|
Long roleId = cmd.getRoleId();
|
||||||
String accountName = cmd.getAccountName();
|
String accountName = cmd.getAccountName();
|
||||||
String newAccountName = cmd.getNewName();
|
String newAccountName = cmd.getNewName();
|
||||||
String networkDomain = cmd.getNetworkDomain();
|
String networkDomain = cmd.getNetworkDomain();
|
||||||
@ -1700,6 +1706,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
account = _accountDao.findEnabledAccount(accountName, domainId);
|
account = _accountDao.findEnabledAccount(accountName, domainId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final AccountVO acctForUpdate = _accountDao.findById(account.getId());
|
||||||
|
|
||||||
// Check if account exists
|
// Check if account exists
|
||||||
if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||||
s_logger.error("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
|
s_logger.error("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
|
||||||
@ -1712,25 +1720,48 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if user performing the action is allowed to modify this account
|
// Check if user performing the action is allowed to modify this account
|
||||||
checkAccess(getCurrentCallingAccount(), _domainMgr.getDomain(account.getDomainId()));
|
Account caller = getCurrentCallingAccount();
|
||||||
|
checkAccess(caller, _domainMgr.getDomain(account.getDomainId()));
|
||||||
|
|
||||||
// check if the given account name is unique in this domain for updating
|
if(newAccountName != null) {
|
||||||
Account duplicateAcccount = _accountDao.findActiveAccount(newAccountName, domainId);
|
|
||||||
if (duplicateAcccount != null && duplicateAcccount.getId() != account.getId()) {
|
if (newAccountName.isEmpty()) {
|
||||||
throw new InvalidParameterValueException(
|
throw new InvalidParameterValueException("The new account name for account '" + account.getUuid() + "' " +
|
||||||
"There already exists an account with the name:" + newAccountName + " in the domain:" + domainId + " with existing account id:" + duplicateAcccount.getId());
|
"within domain '" + domainId + "' is empty string. Account will be not renamed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the new proposed account name is absent in the domain
|
||||||
|
Account existingAccount = _accountDao.findActiveAccount(newAccountName, domainId);
|
||||||
|
if (existingAccount != null && existingAccount.getId() != account.getId()) {
|
||||||
|
throw new InvalidParameterValueException("The account with the proposed name '" +
|
||||||
|
newAccountName + "' exists in the domain '" +
|
||||||
|
domainId + "' with existing account id '" + existingAccount.getId() + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
acctForUpdate.setAccountName(newAccountName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkDomain != null && !networkDomain.isEmpty()) {
|
if (networkDomain != null && !networkDomain.isEmpty()) {
|
||||||
if (!NetUtils.verifyDomainName(networkDomain)) {
|
if (!NetUtils.verifyDomainName(networkDomain)) {
|
||||||
throw new InvalidParameterValueException(
|
throw new InvalidParameterValueException("Invalid network domain or format. " +
|
||||||
"Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
|
"Total length shouldn't exceed 190 chars. Every domain part must be between 1 and 63 " +
|
||||||
|
"characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
|
||||||
+ "and the hyphen ('-'); can't start or end with \"-\"");
|
+ "and the hyphen ('-'); can't start or end with \"-\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final AccountVO acctForUpdate = _accountDao.findById(account.getId());
|
|
||||||
acctForUpdate.setAccountName(newAccountName);
|
if (roleId != null) {
|
||||||
|
final List<Role> roles = cmd.roleService.listRoles();
|
||||||
|
final boolean roleNotFound = roles.stream().filter(r -> r.getId() == roleId).count() == 0;
|
||||||
|
if (roleNotFound) {
|
||||||
|
throw new InvalidParameterValueException("Role with ID '" + roleId.toString() + "' " +
|
||||||
|
"is not found or not available for the account '" + account.getUuid() + "' " +
|
||||||
|
"in the domain '" + domainId + "'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
acctForUpdate.setRoleId(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
if (networkDomain != null) {
|
if (networkDomain != null) {
|
||||||
if (networkDomain.isEmpty()) {
|
if (networkDomain.isEmpty()) {
|
||||||
@ -1741,17 +1772,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Account accountFinal = account;
|
final Account accountFinal = account;
|
||||||
success = Transaction.execute(new TransactionCallback<Boolean>() {
|
success = Transaction.execute((TransactionCallback<Boolean>) status -> {
|
||||||
@Override
|
boolean success1 = _accountDao.update(accountFinal.getId(), acctForUpdate);
|
||||||
public Boolean doInTransaction(TransactionStatus status) {
|
|
||||||
boolean success = _accountDao.update(accountFinal.getId(), acctForUpdate);
|
|
||||||
|
|
||||||
if (details != null && success) {
|
if (details != null && success1) {
|
||||||
_accountDetailsDao.update(accountFinal.getId(), details);
|
_accountDetailsDao.update(accountFinal.getId(), details);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success1;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|||||||
@ -226,7 +226,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
|||||||
|
|
||||||
private void prepareMockAndExecuteUpdateUserTest(int numberOfExpectedCallsForSetEmailAndSetTimeZone) {
|
private void prepareMockAndExecuteUpdateUserTest(int numberOfExpectedCallsForSetEmailAndSetTimeZone) {
|
||||||
Mockito.doReturn(userVoMock).when(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
|
Mockito.doReturn(userVoMock).when(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
|
||||||
Mockito.doNothing().when(accountManagerImpl).validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
Mockito.doNothing().when(accountManagerImpl).validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
Mockito.doReturn(accountMock).when(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
|
Mockito.doReturn(accountMock).when(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
|
||||||
|
|
||||||
Mockito.doNothing().when(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
Mockito.doNothing().when(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
@ -242,7 +242,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
|||||||
InOrder inOrder = Mockito.inOrder(userVoMock, accountManagerImpl, userDaoMock, userAccountDaoMock);
|
InOrder inOrder = Mockito.inOrder(userVoMock, accountManagerImpl, userDaoMock, userAccountDaoMock);
|
||||||
|
|
||||||
inOrder.verify(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
|
inOrder.verify(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
|
||||||
inOrder.verify(accountManagerImpl).validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
inOrder.verify(accountManagerImpl).validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
inOrder.verify(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
|
inOrder.verify(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
|
||||||
|
|
||||||
inOrder.verify(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
inOrder.verify(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
@ -275,7 +275,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void validateAndUpdatApiAndSecretKeyIfNeededTestNoKeys() {
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestNoKeys() {
|
||||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
Mockito.verify(accountDaoMock, Mockito.times(0)).findUserAccountByApiKey(Mockito.anyString());
|
Mockito.verify(accountDaoMock, Mockito.times(0)).findUserAccountByApiKey(Mockito.anyString());
|
||||||
}
|
}
|
||||||
@ -284,14 +284,14 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
|||||||
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlyApiKeyInformed() {
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlyApiKeyInformed() {
|
||||||
Mockito.doReturn("apiKey").when(UpdateUserCmdMock).getApiKey();
|
Mockito.doReturn("apiKey").when(UpdateUserCmdMock).getApiKey();
|
||||||
|
|
||||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidParameterValueException.class)
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlySecretKeyInformed() {
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlySecretKeyInformed() {
|
||||||
Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
|
Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
|
||||||
|
|
||||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidParameterValueException.class)
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
@ -308,7 +308,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
|||||||
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
||||||
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||||
|
|
||||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -327,7 +327,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
|||||||
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
||||||
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||||
|
|
||||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
Mockito.verify(accountDaoMock).findUserAccountByApiKey(apiKey);
|
Mockito.verify(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||||
Mockito.verify(userVoMock).setApiKey(apiKey);
|
Mockito.verify(userVoMock).setApiKey(apiKey);
|
||||||
|
|||||||
@ -30,7 +30,7 @@ from marvin.lib.base import (Domain,
|
|||||||
User,
|
User,
|
||||||
NATRule,
|
NATRule,
|
||||||
Template,
|
Template,
|
||||||
PublicIPAddress)
|
PublicIPAddress, Role)
|
||||||
from marvin.lib.common import (get_domain,
|
from marvin.lib.common import (get_domain,
|
||||||
get_zone,
|
get_zone,
|
||||||
get_test_template,
|
get_test_template,
|
||||||
@ -67,6 +67,11 @@ class Services:
|
|||||||
# username
|
# username
|
||||||
"password": "fr3sca",
|
"password": "fr3sca",
|
||||||
},
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "MarvinFake Role",
|
||||||
|
"type": "User",
|
||||||
|
"description": "Fake Role created by Marvin test"
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"email": "user@test.com",
|
"email": "user@test.com",
|
||||||
"firstname": "User",
|
"firstname": "User",
|
||||||
@ -261,6 +266,53 @@ class TestAccounts(cloudstackTestCase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "basic", "eip", "advancedns", "sg"],
|
||||||
|
required_hardware="false")
|
||||||
|
def test_02_update_account(self):
|
||||||
|
"""
|
||||||
|
Tests that accounts can be updated with new name, network domain, dynamic role
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
dynamic_roles_active = self.apiclient.listCapabilities(listCapabilities.listCapabilitiesCmd()).dynamicrolesenabled
|
||||||
|
if not dynamic_roles_active:
|
||||||
|
self.skipTest("Dynamic Role-Based API checker not enabled, skipping test")
|
||||||
|
|
||||||
|
ts = str(time.time())
|
||||||
|
network_domain = 'mycloud.com'
|
||||||
|
|
||||||
|
account = Account.create(self.apiclient, self.services['account'])
|
||||||
|
self.cleanup.append(account)
|
||||||
|
|
||||||
|
role = Role.create(self.apiclient, self.services['role'])
|
||||||
|
self.cleanup.append(role)
|
||||||
|
|
||||||
|
account.update(self.apiclient, newname=account.name + ts)
|
||||||
|
account.update(self.apiclient, roleid=role.id)
|
||||||
|
account.update(self.apiclient, networkdomain=network_domain)
|
||||||
|
|
||||||
|
list_accounts_response = list_accounts(self.apiclient, id=account.id)
|
||||||
|
test_account = list_accounts_response[0]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
test_account.roleid, role.id,
|
||||||
|
"Check the role for the account is changed")
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
test_account.networkdomain, network_domain,
|
||||||
|
"Check the domain for the account is changed")
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
test_account.name, account.name + ts,
|
||||||
|
"Check the name for the account is changed")
|
||||||
|
|
||||||
|
try:
|
||||||
|
account.update(self.apiclient, newname="")
|
||||||
|
self.fail("Account name change to empty name succeeded. Must be error.")
|
||||||
|
except CloudstackAPIException:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestRemoveUserFromAccount(cloudstackTestCase):
|
class TestRemoveUserFromAccount(cloudstackTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
143
tools/docker/Dockerfile.smokedev
Normal file
143
tools/docker/Dockerfile.smokedev
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# CloudStack-simulator build
|
||||||
|
|
||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
|
||||||
|
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0-SNAPSHOT"
|
||||||
|
|
||||||
|
RUN apt-get -y update && apt-get install -y \
|
||||||
|
genisoimage \
|
||||||
|
libffi-dev \
|
||||||
|
libssl-dev \
|
||||||
|
git \
|
||||||
|
sudo \
|
||||||
|
ipmitool \
|
||||||
|
maven \
|
||||||
|
openjdk-8-jdk \
|
||||||
|
python-dev \
|
||||||
|
python-setuptools \
|
||||||
|
python-pip \
|
||||||
|
python-mysql.connector \
|
||||||
|
supervisor \
|
||||||
|
python-crypto \
|
||||||
|
python-openssl
|
||||||
|
|
||||||
|
RUN echo 'mysql-server mysql-server/root_password password root' | debconf-set-selections; \
|
||||||
|
echo 'mysql-server mysql-server/root_password_again password root' | debconf-set-selections;
|
||||||
|
|
||||||
|
RUN apt-get install -qqy mysql-server && \
|
||||||
|
apt-get clean all && \
|
||||||
|
mkdir /var/run/mysqld; \
|
||||||
|
chown mysql /var/run/mysqld
|
||||||
|
|
||||||
|
#
|
||||||
|
# this package is needed if one wants to run marvin tests from
|
||||||
|
# inside the running simulator.
|
||||||
|
#
|
||||||
|
RUN pip install pyOpenSSL
|
||||||
|
|
||||||
|
RUN echo '''sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"''' >> /etc/mysql/mysql.conf.d/mysqld.cnf
|
||||||
|
RUN (/usr/bin/mysqld_safe &); sleep 5; mysqladmin -u root -proot password ''
|
||||||
|
|
||||||
|
COPY agent /root/agent
|
||||||
|
COPY api /root/api
|
||||||
|
COPY build /root/build
|
||||||
|
COPY client /root/client
|
||||||
|
COPY cloud-cli /root/cloud-cli
|
||||||
|
COPY cloudstack.iml /root/cloudstack.iml
|
||||||
|
COPY core /root/core
|
||||||
|
COPY debian /root/debian
|
||||||
|
COPY deps /root/deps
|
||||||
|
COPY developer /root/developer
|
||||||
|
COPY engine /root/engine
|
||||||
|
COPY framework /root/framework
|
||||||
|
COPY LICENSE.header /root/LICENSE.header
|
||||||
|
COPY LICENSE /root/LICENSE
|
||||||
|
COPY maven-standard /root/maven-standard
|
||||||
|
COPY NOTICE /root/NOTICE
|
||||||
|
COPY packaging /root/packaging
|
||||||
|
COPY plugins /root/plugins
|
||||||
|
COPY pom.xml /root/pom.xml
|
||||||
|
COPY python /root/python
|
||||||
|
COPY quickcloud /root/quickcloud
|
||||||
|
COPY requirements.txt /root/requirements.txt
|
||||||
|
COPY scripts /root/scripts
|
||||||
|
COPY server /root/server
|
||||||
|
COPY services /root/services
|
||||||
|
COPY setup /root/setup
|
||||||
|
COPY systemvm /root/systemvm
|
||||||
|
COPY target /root/target
|
||||||
|
COPY test/bindirbak /root/test/bindirbak
|
||||||
|
COPY test/conf /root/test/conf
|
||||||
|
COPY test/metadata /root/test/metadata
|
||||||
|
COPY test/pom.xml /root/test/pom.xml
|
||||||
|
COPY test/scripts /root/test/scripts
|
||||||
|
COPY test/selenium /root/test/selenium
|
||||||
|
COPY test/systemvm /root/test/systemvm
|
||||||
|
COPY test/target /root/test/target
|
||||||
|
COPY tools/pom.xml /root/tools/pom.xml
|
||||||
|
COPY tools/apidoc /root/tools/apidoc
|
||||||
|
COPY tools/checkstyle /root/tools/checkstyle
|
||||||
|
COPY tools/devcloud4/pom.xml /root/tools/devcloud4/pom.xml
|
||||||
|
COPY tools/devcloud-kvm/pom.xml /root/tools/devcloud-kvm/pom.xml
|
||||||
|
COPY tools/marvin/pom.xml /root/tools/marvin/pom.xml
|
||||||
|
COPY tools/pom.xml /root/tools/pom.xml
|
||||||
|
COPY ui /root/ui
|
||||||
|
COPY usage /root/usage
|
||||||
|
COPY utils /root/utils
|
||||||
|
COPY vmware-base /root/vmware-base
|
||||||
|
|
||||||
|
RUN cd /root && mvn -Pdeveloper -Dsimulator -DskipTests -pl "!:cloud-marvin" install
|
||||||
|
|
||||||
|
RUN (/usr/bin/mysqld_safe &) && \
|
||||||
|
sleep 5 && \
|
||||||
|
cd /root && \
|
||||||
|
mvn -Pdeveloper -pl developer -Ddeploydb && \
|
||||||
|
mvn -Pdeveloper -pl developer -Ddeploydb-simulator
|
||||||
|
|
||||||
|
COPY tools/marvin /root/tools/marvin
|
||||||
|
COPY tools/docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
COPY tools/docker/docker_run_tests.sh /root
|
||||||
|
|
||||||
|
RUN cd /root && mvn -Pdeveloper -Dsimulator -DskipTests -pl ":cloud-marvin"
|
||||||
|
|
||||||
|
RUN MARVIN_FILE=`find /root/tools/marvin/dist/ -name "Marvin*.tar.gz"` && pip install $MARVIN_FILE
|
||||||
|
|
||||||
|
COPY test/integration /root/test/integration
|
||||||
|
COPY tools /root/tools
|
||||||
|
|
||||||
|
RUN pip install --upgrade pyOpenSSL
|
||||||
|
|
||||||
|
EXPOSE 8080 8096
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
CMD ["/usr/bin/supervisord"]
|
||||||
|
|
||||||
|
# --------------------------------
|
||||||
|
#
|
||||||
|
# docker run -v ~/dev/tmp:/tmp -v ~/IdeaProjects/cloudstack/test/integration/smoke:/root/test/integration/smoke -it
|
||||||
|
# --name simulator -p 8080:8080 -p8096:8096 simulator:4.12
|
||||||
|
#
|
||||||
|
# docker exec -it simulator bash
|
||||||
|
#
|
||||||
|
# cat /root/docker_run_tests.sh
|
||||||
|
# for instructions
|
||||||
|
#
|
||||||
50
tools/docker/docker_run_tests.sh
Normal file
50
tools/docker/docker_run_tests.sh
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
MODE=${1:-advanced}
|
||||||
|
SUITE=${2:-smoke}
|
||||||
|
|
||||||
|
export MARVIN_CONFIG=setup/dev/$MODE.cfg
|
||||||
|
export TEST_SUITE=test/integration/$SUITE
|
||||||
|
export ZONE_NAME=Sandbox-simulator
|
||||||
|
|
||||||
|
cd /root
|
||||||
|
|
||||||
|
python tools/marvin/marvin/deployDataCenter.py -i setup/dev/$MODE.cfg
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
RUN WHOLE '$SUITE' SUITE
|
||||||
|
--------------------------
|
||||||
|
nosetests-2.7 \
|
||||||
|
--with-marvin \
|
||||||
|
--marvin-config=${MARVIN_CONFIG} \
|
||||||
|
-w ${TEST_SUITE} \
|
||||||
|
--with-xunit \
|
||||||
|
--xunit-file=/tmp/bvt_selfservice_cases.xml \
|
||||||
|
--zone=${ZONE_NAME} \
|
||||||
|
--hypervisor=simulator \
|
||||||
|
-a tags=$MODE,required_hardware=false
|
||||||
|
--------------------------
|
||||||
|
OR INDIVIDUAL TEST LIKE
|
||||||
|
--------------------------
|
||||||
|
nosetests-2.7 -s --with-marvin --marvin-config=${MARVIN_CONFIG} --zone=${ZONE_NAME} \
|
||||||
|
--hypervisor=simulator -a tags=$MODE,required_hardware=false \
|
||||||
|
test/integration/smoke/test_accounts.py:TestAccounts
|
||||||
|
--------------------------
|
||||||
|
EOF
|
||||||
@ -32,8 +32,10 @@ import time
|
|||||||
import hashlib
|
import hashlib
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
|
||||||
class Domain:
|
class Domain:
|
||||||
""" Domain Life Cycle """
|
""" Domain Life Cycle """
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -174,6 +176,7 @@ class RolePermission:
|
|||||||
|
|
||||||
class Account:
|
class Account:
|
||||||
""" Account Life Cycle """
|
""" Account Life Cycle """
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -238,9 +241,19 @@ class Account:
|
|||||||
cmd.lock = lock
|
cmd.lock = lock
|
||||||
apiclient.disableAccount(cmd)
|
apiclient.disableAccount(cmd)
|
||||||
|
|
||||||
|
def update(self, apiclient, roleid=None, newname=None, networkdomain=""):
|
||||||
|
"""Update account"""
|
||||||
|
cmd = updateAccount.updateAccountCmd()
|
||||||
|
cmd.id = self.id
|
||||||
|
cmd.networkdomain = networkdomain
|
||||||
|
cmd.newname = newname
|
||||||
|
cmd.roleid = roleid
|
||||||
|
apiclient.updateAccount(cmd)
|
||||||
|
|
||||||
|
|
||||||
class User:
|
class User:
|
||||||
""" User Life Cycle """
|
""" User Life Cycle """
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -342,6 +355,7 @@ class VirtualMachine:
|
|||||||
EXPUNGING = EXPUNGING
|
EXPUNGING = EXPUNGING
|
||||||
STOPPING = STOPPING
|
STOPPING = STOPPING
|
||||||
STARTING = STARTING
|
STARTING = STARTING
|
||||||
|
|
||||||
# Varibles denoting VM state - end
|
# Varibles denoting VM state - end
|
||||||
|
|
||||||
def __init__(self, items, services):
|
def __init__(self, items, services):
|
||||||
@ -941,6 +955,7 @@ class VirtualMachine:
|
|||||||
class Volume:
|
class Volume:
|
||||||
"""Manage Volume Life cycle
|
"""Manage Volume Life cycle
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -1147,6 +1162,7 @@ class Snapshot:
|
|||||||
# Variables denoting possible Snapshot states - start
|
# Variables denoting possible Snapshot states - start
|
||||||
BACKED_UP = BACKED_UP
|
BACKED_UP = BACKED_UP
|
||||||
BACKING_UP = BACKING_UP
|
BACKING_UP = BACKING_UP
|
||||||
|
|
||||||
# Variables denoting possible Snapshot states - end
|
# Variables denoting possible Snapshot states - end
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
@ -1336,7 +1352,6 @@ class Template:
|
|||||||
if "directdownload" in services:
|
if "directdownload" in services:
|
||||||
cmd.directdownload = services["directdownload"]
|
cmd.directdownload = services["directdownload"]
|
||||||
|
|
||||||
|
|
||||||
# Register Template
|
# Register Template
|
||||||
template = apiclient.registerTemplate(cmd)
|
template = apiclient.registerTemplate(cmd)
|
||||||
|
|
||||||
@ -1865,7 +1880,6 @@ class StaticNATRule:
|
|||||||
|
|
||||||
|
|
||||||
class EgressFireWallRule:
|
class EgressFireWallRule:
|
||||||
|
|
||||||
"""Manage Egress Firewall rule"""
|
"""Manage Egress Firewall rule"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
@ -1911,7 +1925,6 @@ class EgressFireWallRule:
|
|||||||
|
|
||||||
|
|
||||||
class FireWallRule:
|
class FireWallRule:
|
||||||
|
|
||||||
"""Manage Firewall rule"""
|
"""Manage Firewall rule"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
@ -1958,7 +1971,6 @@ class FireWallRule:
|
|||||||
|
|
||||||
|
|
||||||
class Autoscale:
|
class Autoscale:
|
||||||
|
|
||||||
"""Manage Auto scale"""
|
"""Manage Auto scale"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
@ -2115,7 +2127,6 @@ class Autoscale:
|
|||||||
|
|
||||||
|
|
||||||
class ServiceOffering:
|
class ServiceOffering:
|
||||||
|
|
||||||
"""Manage service offerings cycle"""
|
"""Manage service offerings cycle"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
@ -2321,7 +2332,6 @@ class NetworkOffering:
|
|||||||
if "servicepackagedescription" in services:
|
if "servicepackagedescription" in services:
|
||||||
cmd.details[0]["servicepackagedescription"] = services["servicepackagedescription"]
|
cmd.details[0]["servicepackagedescription"] = services["servicepackagedescription"]
|
||||||
|
|
||||||
|
|
||||||
cmd.availability = 'Optional'
|
cmd.availability = 'Optional'
|
||||||
|
|
||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
@ -2388,8 +2398,10 @@ class SnapshotPolicy:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listSnapshotPolicies(cmd))
|
return (apiclient.listSnapshotPolicies(cmd))
|
||||||
|
|
||||||
|
|
||||||
class GuestOs:
|
class GuestOs:
|
||||||
"""Guest OS calls (currently read-only implemented)"""
|
"""Guest OS calls (currently read-only implemented)"""
|
||||||
|
|
||||||
def __init(self, items):
|
def __init(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -2416,6 +2428,7 @@ class GuestOs:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return (apiclient.listOsTypes(cmd))
|
return (apiclient.listOsTypes(cmd))
|
||||||
|
|
||||||
|
|
||||||
class Hypervisor:
|
class Hypervisor:
|
||||||
"""Manage Hypervisor"""
|
"""Manage Hypervisor"""
|
||||||
|
|
||||||
@ -2731,7 +2744,8 @@ class Host:
|
|||||||
retry_interval = 10
|
retry_interval = 10
|
||||||
num_tries = 10
|
num_tries = 10
|
||||||
|
|
||||||
wait_result, return_val = wait_until(retry_interval, num_tries, Host._check_resource_state, apiclient, self.id, HOST_RS_MAINTENANCE)
|
wait_result, return_val = wait_until(retry_interval, num_tries, Host._check_resource_state, apiclient, self.id,
|
||||||
|
HOST_RS_MAINTENANCE)
|
||||||
|
|
||||||
if not wait_result:
|
if not wait_result:
|
||||||
raise Exception(return_val)
|
raise Exception(return_val)
|
||||||
@ -2812,7 +2826,8 @@ class Host:
|
|||||||
validationresult = validateList(hosts)
|
validationresult = validateList(hosts)
|
||||||
if validationresult[0] == FAIL:
|
if validationresult[0] == FAIL:
|
||||||
raise Exception("Host list validation failed: %s" % validationresult[2])
|
raise Exception("Host list validation failed: %s" % validationresult[2])
|
||||||
elif str(hosts[0].state).lower().decode("string_escape") == str(state).lower() and str(hosts[0].resourcestate).lower().decode("string_escape") == str(resourcestate).lower():
|
elif str(hosts[0].state).lower().decode("string_escape") == str(state).lower() and str(
|
||||||
|
hosts[0].resourcestate).lower().decode("string_escape") == str(resourcestate).lower():
|
||||||
returnValue = [PASS, None]
|
returnValue = [PASS, None]
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -2822,6 +2837,7 @@ class Host:
|
|||||||
timeout -= 60
|
timeout -= 60
|
||||||
return returnValue
|
return returnValue
|
||||||
|
|
||||||
|
|
||||||
class StoragePool:
|
class StoragePool:
|
||||||
"""Manage Storage pools (Primary Storage)"""
|
"""Manage Storage pools (Primary Storage)"""
|
||||||
|
|
||||||
@ -2970,6 +2986,7 @@ class StoragePool:
|
|||||||
timeout -= 60
|
timeout -= 60
|
||||||
return returnValue
|
return returnValue
|
||||||
|
|
||||||
|
|
||||||
class Network:
|
class Network:
|
||||||
"""Manage Network pools"""
|
"""Manage Network pools"""
|
||||||
|
|
||||||
@ -3389,6 +3406,7 @@ class Zone:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listZones(cmd))
|
return (apiclient.listZones(cmd))
|
||||||
|
|
||||||
|
|
||||||
class Pod:
|
class Pod:
|
||||||
"""Manage Pod"""
|
"""Manage Pod"""
|
||||||
|
|
||||||
@ -3433,6 +3451,7 @@ class Pod:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return apiclient.updatePod(cmd)
|
return apiclient.updatePod(cmd)
|
||||||
|
|
||||||
|
|
||||||
class PublicIpRange:
|
class PublicIpRange:
|
||||||
"""Manage VlanIpRange"""
|
"""Manage VlanIpRange"""
|
||||||
|
|
||||||
@ -3540,6 +3559,7 @@ class PortablePublicIpRange:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listPortableIpRanges(cmd))
|
return (apiclient.listPortableIpRanges(cmd))
|
||||||
|
|
||||||
|
|
||||||
class SecondaryStagingStore:
|
class SecondaryStagingStore:
|
||||||
"""Manage Staging Store"""
|
"""Manage Staging Store"""
|
||||||
|
|
||||||
@ -4036,7 +4056,6 @@ class Configurations:
|
|||||||
cmd.storageid = storageid
|
cmd.storageid = storageid
|
||||||
apiclient.updateConfiguration(cmd)
|
apiclient.updateConfiguration(cmd)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def list(cls, apiclient, **kwargs):
|
def list(cls, apiclient, **kwargs):
|
||||||
"""Lists configurations"""
|
"""Lists configurations"""
|
||||||
@ -4054,6 +4073,7 @@ class Configurations:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return (apiclient.listCapabilities(cmd))
|
return (apiclient.listCapabilities(cmd))
|
||||||
|
|
||||||
|
|
||||||
class NetScaler:
|
class NetScaler:
|
||||||
"""Manage external netscaler device"""
|
"""Manage external netscaler device"""
|
||||||
|
|
||||||
@ -4122,6 +4142,7 @@ class NetScaler:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listNetscalerLoadBalancers(cmd))
|
return (apiclient.listNetscalerLoadBalancers(cmd))
|
||||||
|
|
||||||
|
|
||||||
class NiciraNvp:
|
class NiciraNvp:
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
@ -4501,7 +4522,6 @@ class VPC:
|
|||||||
cmd.resume = resume
|
cmd.resume = resume
|
||||||
return (apiclient.migrateVPC(cmd))
|
return (apiclient.migrateVPC(cmd))
|
||||||
|
|
||||||
|
|
||||||
def delete(self, apiclient):
|
def delete(self, apiclient):
|
||||||
"""Delete VPC network"""
|
"""Delete VPC network"""
|
||||||
|
|
||||||
@ -4603,8 +4623,10 @@ class AffinityGroup:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return apiclient.listAffinityGroups(cmd)
|
return apiclient.listAffinityGroups(cmd)
|
||||||
|
|
||||||
|
|
||||||
class StaticRoute:
|
class StaticRoute:
|
||||||
"""Manage static route lifecycle"""
|
"""Manage static route lifecycle"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -4637,6 +4659,7 @@ class StaticRoute:
|
|||||||
|
|
||||||
class VNMC:
|
class VNMC:
|
||||||
"""Manage VNMC lifecycle"""
|
"""Manage VNMC lifecycle"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -4832,6 +4855,7 @@ class InstanceGroup:
|
|||||||
|
|
||||||
class ASA1000V:
|
class ASA1000V:
|
||||||
"""Manage ASA 1000v lifecycle"""
|
"""Manage ASA 1000v lifecycle"""
|
||||||
|
|
||||||
def create(cls, apiclient, hostname, insideportprofile,
|
def create(cls, apiclient, hostname, insideportprofile,
|
||||||
clusterid, physicalnetworkid):
|
clusterid, physicalnetworkid):
|
||||||
"""Registers ASA 1000v appliance"""
|
"""Registers ASA 1000v appliance"""
|
||||||
@ -4860,8 +4884,10 @@ class ASA1000V:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listCiscoAsa1000vResources(cmd))
|
return (apiclient.listCiscoAsa1000vResources(cmd))
|
||||||
|
|
||||||
|
|
||||||
class VmSnapshot:
|
class VmSnapshot:
|
||||||
"""Manage VM Snapshot life cycle"""
|
"""Manage VM Snapshot life cycle"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -4899,8 +4925,10 @@ class VmSnapshot:
|
|||||||
cmd.vmsnapshotid = vmsnapshotid
|
cmd.vmsnapshotid = vmsnapshotid
|
||||||
return apiclient.deleteVMSnapshot(cmd)
|
return apiclient.deleteVMSnapshot(cmd)
|
||||||
|
|
||||||
|
|
||||||
class Region:
|
class Region:
|
||||||
""" Regions related Api """
|
""" Regions related Api """
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -5036,6 +5064,7 @@ class ApplicationLoadBalancer:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listLoadBalancerRules(cmd))
|
return (apiclient.listLoadBalancerRules(cmd))
|
||||||
|
|
||||||
|
|
||||||
class Resources:
|
class Resources:
|
||||||
"""Manage resource limits"""
|
"""Manage resource limits"""
|
||||||
|
|
||||||
@ -5068,8 +5097,10 @@ class Resources:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return (apiclient.updateResourceCount(cmd))
|
return (apiclient.updateResourceCount(cmd))
|
||||||
|
|
||||||
|
|
||||||
class NIC:
|
class NIC:
|
||||||
"""NIC related API"""
|
"""NIC related API"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -5099,8 +5130,10 @@ class NIC:
|
|||||||
cmd.listall = True
|
cmd.listall = True
|
||||||
return (apiclient.listNics(cmd))
|
return (apiclient.listNics(cmd))
|
||||||
|
|
||||||
|
|
||||||
class SimulatorMock:
|
class SimulatorMock:
|
||||||
"""Manage simulator mock lifecycle"""
|
"""Manage simulator mock lifecycle"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -5142,8 +5175,10 @@ class SimulatorMock:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
class Usage:
|
class Usage:
|
||||||
"""Manage Usage Generation"""
|
"""Manage Usage Generation"""
|
||||||
|
|
||||||
def __init__(self, items):
|
def __init__(self, items):
|
||||||
self.__dict__.update(items)
|
self.__dict__.update(items)
|
||||||
|
|
||||||
@ -5172,6 +5207,7 @@ class Usage:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return (apiclient.generateUsageRecords(cmd))
|
return (apiclient.generateUsageRecords(cmd))
|
||||||
|
|
||||||
|
|
||||||
class TrafficType:
|
class TrafficType:
|
||||||
"""Manage different traffic types in the setup"""
|
"""Manage different traffic types in the setup"""
|
||||||
|
|
||||||
@ -5186,6 +5222,7 @@ class TrafficType:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return (apiclient.listTrafficTypes(cmd))
|
return (apiclient.listTrafficTypes(cmd))
|
||||||
|
|
||||||
|
|
||||||
class StorageNetworkIpRange:
|
class StorageNetworkIpRange:
|
||||||
"""Manage Storage Network Ip Range"""
|
"""Manage Storage Network Ip Range"""
|
||||||
|
|
||||||
@ -5200,6 +5237,7 @@ class StorageNetworkIpRange:
|
|||||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||||
return (apiclient.listStorageNetworkIpRange(cmd))
|
return (apiclient.listStorageNetworkIpRange(cmd))
|
||||||
|
|
||||||
|
|
||||||
class RegisteredServicePackage:
|
class RegisteredServicePackage:
|
||||||
"""Manage ServicePackage registered with NCC"""
|
"""Manage ServicePackage registered with NCC"""
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user