mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-25 09:12:38 +02: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.
|
||||
|
||||
cloudstack/tools/docker/Dockerfile
|
||||
cloudstack/tools/docker/Dockerfile.smokedev
|
||||
.dockerignore
|
||||
.idea
|
||||
.git
|
||||
|
||||
@ -21,6 +21,7 @@ import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.response.RoleResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
@ -48,16 +49,19 @@ public class UpdateAccountCmd extends BaseCmd {
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@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;
|
||||
|
||||
@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;
|
||||
|
||||
@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;
|
||||
|
||||
@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;
|
||||
|
||||
@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")
|
||||
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;
|
||||
|
||||
@Inject
|
||||
@ -87,6 +91,8 @@ public class UpdateAccountCmd extends BaseCmd {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getRoleId() { return roleId; }
|
||||
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
@ -37,8 +37,10 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.QuerySelector;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
@ -1019,8 +1021,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
@DB
|
||||
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
||||
@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,
|
||||
final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID,
|
||||
public UserAccount createUserAccount(final String userName, final String password, final String firstName,
|
||||
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) {
|
||||
|
||||
if (accountName == null) {
|
||||
@ -1155,7 +1160,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
UserVO user = retrieveAndValidateUser(updateUserCmd);
|
||||
s_logger.debug("Updating user with Id: " + user.getUuid());
|
||||
|
||||
validateAndUpdatApiAndSecretKeyIfNeeded(updateUserCmd, user);
|
||||
validateAndUpdateApiAndSecretKeyIfNeeded(updateUserCmd, user);
|
||||
Account account = retrieveAndValidateAccount(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.
|
||||
* </ul>
|
||||
*/
|
||||
protected void validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
||||
protected void validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
||||
String apiKey = updateUserCmd.getApiKey();
|
||||
String secretKey = updateUserCmd.getSecretKey();
|
||||
|
||||
@ -1687,6 +1692,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
public AccountVO updateAccount(UpdateAccountCmd cmd) {
|
||||
Long accountId = cmd.getId();
|
||||
Long domainId = cmd.getDomainId();
|
||||
Long roleId = cmd.getRoleId();
|
||||
String accountName = cmd.getAccountName();
|
||||
String newAccountName = cmd.getNewName();
|
||||
String networkDomain = cmd.getNetworkDomain();
|
||||
@ -1700,6 +1706,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
account = _accountDao.findEnabledAccount(accountName, domainId);
|
||||
}
|
||||
|
||||
final AccountVO acctForUpdate = _accountDao.findById(account.getId());
|
||||
|
||||
// Check if account exists
|
||||
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);
|
||||
@ -1712,25 +1720,48 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
}
|
||||
|
||||
// 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
|
||||
Account duplicateAcccount = _accountDao.findActiveAccount(newAccountName, domainId);
|
||||
if (duplicateAcccount != null && duplicateAcccount.getId() != account.getId()) {
|
||||
throw new InvalidParameterValueException(
|
||||
"There already exists an account with the name:" + newAccountName + " in the domain:" + domainId + " with existing account id:" + duplicateAcccount.getId());
|
||||
if(newAccountName != null) {
|
||||
|
||||
if (newAccountName.isEmpty()) {
|
||||
throw new InvalidParameterValueException("The new account name for account '" + account.getUuid() + "' " +
|
||||
"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 (!NetUtils.verifyDomainName(networkDomain)) {
|
||||
throw new InvalidParameterValueException(
|
||||
"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', "
|
||||
throw new InvalidParameterValueException("Invalid network domain or format. " +
|
||||
"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 \"-\"");
|
||||
}
|
||||
}
|
||||
|
||||
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.isEmpty()) {
|
||||
@ -1741,17 +1772,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
}
|
||||
|
||||
final Account accountFinal = account;
|
||||
success = Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
boolean success = _accountDao.update(accountFinal.getId(), acctForUpdate);
|
||||
success = Transaction.execute((TransactionCallback<Boolean>) status -> {
|
||||
boolean success1 = _accountDao.update(accountFinal.getId(), acctForUpdate);
|
||||
|
||||
if (details != null && success) {
|
||||
_accountDetailsDao.update(accountFinal.getId(), details);
|
||||
}
|
||||
|
||||
return success;
|
||||
if (details != null && success1) {
|
||||
_accountDetailsDao.update(accountFinal.getId(), details);
|
||||
}
|
||||
|
||||
return success1;
|
||||
});
|
||||
|
||||
if (success) {
|
||||
|
||||
@ -226,7 +226,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||
|
||||
private void prepareMockAndExecuteUpdateUserTest(int numberOfExpectedCallsForSetEmailAndSetTimeZone) {
|
||||
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.doNothing().when(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
@ -242,7 +242,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||
InOrder inOrder = Mockito.inOrder(userVoMock, accountManagerImpl, userDaoMock, userAccountDaoMock);
|
||||
|
||||
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).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
@ -275,7 +275,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||
|
||||
@Test
|
||||
public void validateAndUpdatApiAndSecretKeyIfNeededTestNoKeys() {
|
||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
|
||||
Mockito.verify(accountDaoMock, Mockito.times(0)).findUserAccountByApiKey(Mockito.anyString());
|
||||
}
|
||||
@ -284,14 +284,14 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlyApiKeyInformed() {
|
||||
Mockito.doReturn("apiKey").when(UpdateUserCmdMock).getApiKey();
|
||||
|
||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlySecretKeyInformed() {
|
||||
Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
|
||||
|
||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
}
|
||||
|
||||
@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));
|
||||
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||
|
||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -327,7 +327,7 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
||||
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||
|
||||
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||
|
||||
Mockito.verify(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||
Mockito.verify(userVoMock).setApiKey(apiKey);
|
||||
|
||||
@ -30,7 +30,7 @@ from marvin.lib.base import (Domain,
|
||||
User,
|
||||
NATRule,
|
||||
Template,
|
||||
PublicIPAddress)
|
||||
PublicIPAddress, Role)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_test_template,
|
||||
@ -67,6 +67,11 @@ class Services:
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"role": {
|
||||
"name": "MarvinFake Role",
|
||||
"type": "User",
|
||||
"description": "Fake Role created by Marvin test"
|
||||
},
|
||||
"user": {
|
||||
"email": "user@test.com",
|
||||
"firstname": "User",
|
||||
@ -261,6 +266,53 @@ class TestAccounts(cloudstackTestCase):
|
||||
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):
|
||||
|
||||
@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
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user