CLOUDSTACK-3049: Implemented role update for account. (#3058)

This commit is contained in:
Bitworks LLC 2019-01-25 19:02:56 +07:00 committed by Gabriel Beims Bräscher
parent 97ddd8dffd
commit d68712eb7b
8 changed files with 500 additions and 182 deletions

View File

@ -16,6 +16,7 @@
# under the License.
cloudstack/tools/docker/Dockerfile
cloudstack/tools/docker/Dockerfile.smokedev
.dockerignore
.idea
.git

View File

@ -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;
}

View File

@ -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) {
if (details != null && success1) {
_accountDetailsDao.update(accountFinal.getId(), details);
}
return success;
}
return success1;
});
if (success) {

View File

@ -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);

View File

@ -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

View 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
#

View 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

View File

@ -32,8 +32,10 @@ import time
import hashlib
import base64
class Domain:
""" Domain Life Cycle """
def __init__(self, items):
self.__dict__.update(items)
@ -174,6 +176,7 @@ class RolePermission:
class Account:
""" Account Life Cycle """
def __init__(self, items):
self.__dict__.update(items)
@ -238,9 +241,19 @@ class Account:
cmd.lock = lock
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:
""" User Life Cycle """
def __init__(self, items):
self.__dict__.update(items)
@ -342,6 +355,7 @@ class VirtualMachine:
EXPUNGING = EXPUNGING
STOPPING = STOPPING
STARTING = STARTING
# Varibles denoting VM state - end
def __init__(self, items, services):
@ -941,6 +955,7 @@ class VirtualMachine:
class Volume:
"""Manage Volume Life cycle
"""
def __init__(self, items):
self.__dict__.update(items)
@ -1147,6 +1162,7 @@ class Snapshot:
# Variables denoting possible Snapshot states - start
BACKED_UP = BACKED_UP
BACKING_UP = BACKING_UP
# Variables denoting possible Snapshot states - end
def __init__(self, items):
@ -1336,7 +1352,6 @@ class Template:
if "directdownload" in services:
cmd.directdownload = services["directdownload"]
# Register Template
template = apiclient.registerTemplate(cmd)
@ -1865,7 +1880,6 @@ class StaticNATRule:
class EgressFireWallRule:
"""Manage Egress Firewall rule"""
def __init__(self, items):
@ -1911,7 +1925,6 @@ class EgressFireWallRule:
class FireWallRule:
"""Manage Firewall rule"""
def __init__(self, items):
@ -1958,7 +1971,6 @@ class FireWallRule:
class Autoscale:
"""Manage Auto scale"""
def __init__(self, items):
@ -2115,7 +2127,6 @@ class Autoscale:
class ServiceOffering:
"""Manage service offerings cycle"""
def __init__(self, items):
@ -2321,7 +2332,6 @@ class NetworkOffering:
if "servicepackagedescription" in services:
cmd.details[0]["servicepackagedescription"] = services["servicepackagedescription"]
cmd.availability = 'Optional'
[setattr(cmd, k, v) for k, v in kwargs.items()]
@ -2388,8 +2398,10 @@ class SnapshotPolicy:
cmd.listall = True
return (apiclient.listSnapshotPolicies(cmd))
class GuestOs:
"""Guest OS calls (currently read-only implemented)"""
def __init(self, items):
self.__dict__.update(items)
@ -2416,6 +2428,7 @@ class GuestOs:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.listOsTypes(cmd))
class Hypervisor:
"""Manage Hypervisor"""
@ -2731,7 +2744,8 @@ class Host:
retry_interval = 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:
raise Exception(return_val)
@ -2812,7 +2826,8 @@ class Host:
validationresult = validateList(hosts)
if validationresult[0] == FAIL:
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]
break
except Exception as e:
@ -2822,6 +2837,7 @@ class Host:
timeout -= 60
return returnValue
class StoragePool:
"""Manage Storage pools (Primary Storage)"""
@ -2970,6 +2986,7 @@ class StoragePool:
timeout -= 60
return returnValue
class Network:
"""Manage Network pools"""
@ -3389,6 +3406,7 @@ class Zone:
cmd.listall = True
return (apiclient.listZones(cmd))
class Pod:
"""Manage Pod"""
@ -3433,6 +3451,7 @@ class Pod:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return apiclient.updatePod(cmd)
class PublicIpRange:
"""Manage VlanIpRange"""
@ -3540,6 +3559,7 @@ class PortablePublicIpRange:
cmd.listall = True
return (apiclient.listPortableIpRanges(cmd))
class SecondaryStagingStore:
"""Manage Staging Store"""
@ -4036,7 +4056,6 @@ class Configurations:
cmd.storageid = storageid
apiclient.updateConfiguration(cmd)
@classmethod
def list(cls, apiclient, **kwargs):
"""Lists configurations"""
@ -4054,6 +4073,7 @@ class Configurations:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.listCapabilities(cmd))
class NetScaler:
"""Manage external netscaler device"""
@ -4122,6 +4142,7 @@ class NetScaler:
cmd.listall = True
return (apiclient.listNetscalerLoadBalancers(cmd))
class NiciraNvp:
def __init__(self, items):
@ -4501,7 +4522,6 @@ class VPC:
cmd.resume = resume
return (apiclient.migrateVPC(cmd))
def delete(self, apiclient):
"""Delete VPC network"""
@ -4603,8 +4623,10 @@ class AffinityGroup:
cmd.listall = True
return apiclient.listAffinityGroups(cmd)
class StaticRoute:
"""Manage static route lifecycle"""
def __init__(self, items):
self.__dict__.update(items)
@ -4637,6 +4659,7 @@ class StaticRoute:
class VNMC:
"""Manage VNMC lifecycle"""
def __init__(self, items):
self.__dict__.update(items)
@ -4832,6 +4855,7 @@ class InstanceGroup:
class ASA1000V:
"""Manage ASA 1000v lifecycle"""
def create(cls, apiclient, hostname, insideportprofile,
clusterid, physicalnetworkid):
"""Registers ASA 1000v appliance"""
@ -4860,8 +4884,10 @@ class ASA1000V:
cmd.listall = True
return (apiclient.listCiscoAsa1000vResources(cmd))
class VmSnapshot:
"""Manage VM Snapshot life cycle"""
def __init__(self, items):
self.__dict__.update(items)
@ -4899,8 +4925,10 @@ class VmSnapshot:
cmd.vmsnapshotid = vmsnapshotid
return apiclient.deleteVMSnapshot(cmd)
class Region:
""" Regions related Api """
def __init__(self, items):
self.__dict__.update(items)
@ -5036,6 +5064,7 @@ class ApplicationLoadBalancer:
cmd.listall = True
return (apiclient.listLoadBalancerRules(cmd))
class Resources:
"""Manage resource limits"""
@ -5068,8 +5097,10 @@ class Resources:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.updateResourceCount(cmd))
class NIC:
"""NIC related API"""
def __init__(self, items):
self.__dict__.update(items)
@ -5099,8 +5130,10 @@ class NIC:
cmd.listall = True
return (apiclient.listNics(cmd))
class SimulatorMock:
"""Manage simulator mock lifecycle"""
def __init__(self, items):
self.__dict__.update(items)
@ -5142,8 +5175,10 @@ class SimulatorMock:
except Exception as e:
raise e
class Usage:
"""Manage Usage Generation"""
def __init__(self, items):
self.__dict__.update(items)
@ -5172,6 +5207,7 @@ class Usage:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.generateUsageRecords(cmd))
class TrafficType:
"""Manage different traffic types in the setup"""
@ -5186,6 +5222,7 @@ class TrafficType:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.listTrafficTypes(cmd))
class StorageNetworkIpRange:
"""Manage Storage Network Ip Range"""
@ -5200,6 +5237,7 @@ class StorageNetworkIpRange:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.listStorageNetworkIpRange(cmd))
class RegisteredServicePackage:
"""Manage ServicePackage registered with NCC"""