You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ta...@apache.org on 2014/04/08 14:26:13 UTC

[58/60] [abbrv] Merge branch 'master' into marvin

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e223d67/tools/marvin/marvin/lib/base.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/lib/base.py
index 589c694,0000000..66ebbf8
mode 100755,000000..100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@@ -1,3651 -1,0 +1,3872 @@@
 +# 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.
 +
 +""" Base class for all Cloudstack resources
 +    -Virtual machine, Volume, Snapshot etc
 +"""
 +
 +import marvin
 +from utils import is_server_ssh_ready, random_gen
 +from marvin.cloudstackAPI import *
 +from marvin.codes import FAILED, PASS
 +from marvin.cloudstackException import GetDetailExceptionInfo
 +from marvin.lib.utils import validateList
 +# Import System modules
 +import time
 +import hashlib
 +import base64
 +
 +
 +class Domain:
 +    """ Domain Life Cycle """
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, name=None, networkdomain=None,
 +               parentdomainid=None):
 +        """Creates an domain"""
 +
 +        cmd = createDomain.createDomainCmd()
 +
 +        if "domainUUID" in services:
 +            cmd.domainid = "-".join([services["domainUUID"], random_gen()])
 +
 +        if name:
 +            cmd.name = "-".join([name, random_gen()])
 +        elif "name" in services:
 +            cmd.name = "-".join([services["name"], random_gen()])
 +
 +        if networkdomain:
 +            cmd.networkdomain = networkdomain
 +        elif "networkdomain" in services:
 +            cmd.networkdomain = services["networkdomain"]
 +
 +        if parentdomainid:
 +            cmd.parentdomainid = parentdomainid
 +        elif "parentdomainid" in services:
 +            cmd.parentdomainid = services["parentdomainid"]
 +        try:
 +            domain = apiclient.createDomain(cmd)
 +            if domain is not None:
 +                return Domain(domain.__dict__)
 +        except Exception as e:
 +            raise e
 +
 +    def delete(self, apiclient, cleanup=None):
 +        """Delete an domain"""
 +        cmd = deleteDomain.deleteDomainCmd()
 +        cmd.id = self.id
 +        if cleanup:
 +            cmd.cleanup = cleanup
 +        apiclient.deleteDomain(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists domains"""
 +        cmd = listDomains.listDomainsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listDomains(cmd))
 +
 +
 +class Account:
 +    """ Account Life Cycle """
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, admin=False, domainid=None):
 +        """Creates an account"""
 +        cmd = createAccount.createAccountCmd()
 +
 +        # 0 - User, 1 - Root Admin, 2 - Domain Admin
 +        cmd.accounttype = 2 if (admin and domainid) else int(admin)
 +
 +        cmd.email = services["email"]
 +        cmd.firstname = services["firstname"]
 +        cmd.lastname = services["lastname"]
 +
 +        cmd.password = services["password"]
 +
 +        username = "-".join([services["username"], random_gen(id=apiclient.id)])
 +        #  Trim username to 99 characters to prevent failure
 +        cmd.username = username[:99] if len(username) > 99 else username
 +
 +        if "accountUUID" in services:
 +            cmd.accountid =  "-".join([services["accountUUID"],random_gen()])
 +
 +        if "userUUID" in services:
 +            cmd.userid = "-".join([services["userUUID"],random_gen()])
 +
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +        account = apiclient.createAccount(cmd)
 +
 +        return Account(account.__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete an account"""
 +        cmd = deleteAccount.deleteAccountCmd()
 +        cmd.id = self.id
 +        apiclient.deleteAccount(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists accounts and provides detailed account information for
 +        listed accounts"""
 +
 +        cmd = listAccounts.listAccountsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listAccounts(cmd))
 +
++    def disable(self, apiclient, lock=False):
++        """Disable an account"""
++        cmd = disableAccount.disableAccountCmd()
++        cmd.id = self.id
++        cmd.lock = lock
++        apiclient.disableAccount(cmd)
++
 +
 +class User:
 +    """ User Life Cycle """
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, account, domainid):
 +        cmd = createUser.createUserCmd()
 +        """Creates an user"""
 +
 +        cmd.account = account
 +        cmd.domainid = domainid
 +        cmd.email = services["email"]
 +        cmd.firstname = services["firstname"]
 +        cmd.lastname = services["lastname"]
 +
 +        if "userUUID" in services:
 +            cmd.userid = "-".join([services["userUUID"],random_gen()])
 +
 +        cmd.password = services["password"]
 +        cmd.username = "-".join([services["username"], random_gen()])
 +        user = apiclient.createUser(cmd)
 +
 +        return User(user.__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete an account"""
 +        cmd = deleteUser.deleteUserCmd()
 +        cmd.id = self.id
 +        apiclient.deleteUser(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists users and provides detailed account information for
 +        listed users"""
 +
 +        cmd = listUsers.listUsersCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listUsers(cmd))
 +
 +    @classmethod
 +    def registerUserKeys(cls, apiclient, userid):
 +        cmd = registerUserKeys.registerUserKeysCmd()
 +        cmd.id = userid
 +        return apiclient.registerUserKeys(cmd)
 +
 +    def update(self, apiclient, **kwargs):
 +        """Updates the user details"""
 +
 +        cmd = updateUser.updateUserCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return (apiclient.updateUser(cmd))
 +
 +    @classmethod
 +    def update(cls, apiclient, id, **kwargs):
 +        """Updates the user details (class method)"""
 +
 +        cmd = updateUser.updateUserCmd()
 +        cmd.id = id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return (apiclient.updateUser(cmd))
 +
 +    @classmethod
 +    def login(cls, apiclient, username, password, domain=None, domainid=None):
 +        """Logins to the CloudStack"""
 +
 +        cmd = login.loginCmd()
 +        cmd.username = username
 +        cmd.password = password
 +        if domain:
 +            cmd.domain = domain
 +        if domainid:
 +            cmd.domainId = domainid
 +        return apiclient.login(cmd)
 +
 +
 +class VirtualMachine:
 +    """Manage virtual machine lifecycle"""
 +
 +    def __init__(self, items, services):
 +        self.__dict__.update(items)
 +        if "username" in services:
 +            self.username = services["username"]
 +        else:
 +            self.username = 'root'
 +        if "password" in services:
 +            self.password = services["password"]
 +        else:
 +            self.password = 'password'
 +        if "ssh_port" in services:
 +            self.ssh_port = services["ssh_port"]
 +        else:
 +            self.ssh_port = 22
 +        self.ssh_client = None
 +        # extract out the ipaddress
 +        self.ipaddress = self.nic[0].ipaddress
 +
 +    @classmethod
 +    def ssh_access_group(cls, apiclient, cmd):
 +        """
 +        Programs the security group with SSH access before deploying virtualmachine
 +        @return:
 +        """
 +        zone_list = Zone.list(
 +            apiclient,
 +            id=cmd.zoneid if cmd.zoneid else None,
 +            domainid=cmd.domainid if cmd.domainid else None
 +        )
 +        zone = zone_list[0]
 +        #check if security groups settings is enabled for the zone
 +        if zone.securitygroupsenabled:
 +            list_security_groups = SecurityGroup.list(
 +                apiclient,
 +                account=cmd.account,
 +                domainid=cmd.domainid,
 +                securitygroupname="basic_sec_grp"
 +            )
 +
 +            if not isinstance(list_security_groups, list):
 +                basic_mode_security_group = SecurityGroup.create(
 +                    apiclient,
 +                    {"name": "basic_sec_grp"},
 +                    cmd.account,
 +                    cmd.domainid,
 +                )
 +                sec_grp_services = {
 +                    "protocol": "TCP",
 +                    "startport": 22,
 +                    "endport": 22,
 +                    "cidrlist": "0.0.0.0/0"
 +                }
 +                #Authorize security group for above ingress rule
 +                basic_mode_security_group.authorize(apiclient, sec_grp_services, account=cmd.account,
 +                    domainid=cmd.domainid)
 +            else:
 +                basic_mode_security_group = list_security_groups[0]
 +
 +            if isinstance(cmd.securitygroupids, list):
 +                cmd.securitygroupids.append(basic_mode_security_group.id)
 +            else:
 +                cmd.securitygroupids = [basic_mode_security_group.id]
 +
 +    @classmethod
 +    def access_ssh_over_nat(cls, apiclient, services, virtual_machine, allow_egress=False):
 +        """
 +        Program NAT and PF rules to open up ssh access to deployed guest
 +        @return:
 +        """
 +        public_ip = PublicIPAddress.create(
 +            apiclient=apiclient,
 +            accountid=virtual_machine.account,
 +            zoneid=virtual_machine.zoneid,
 +            domainid=virtual_machine.domainid,
 +            services=services
 +        )
 +        FireWallRule.create(
 +            apiclient=apiclient,
 +            ipaddressid=public_ip.ipaddress.id,
 +            protocol='TCP',
 +            cidrlist=['0.0.0.0/0'],
 +            startport=22,
 +            endport=22
 +        )
 +        nat_rule = NATRule.create(
 +            apiclient=apiclient,
 +            virtual_machine=virtual_machine,
 +            services=services,
 +            ipaddressid=public_ip.ipaddress.id
 +        )
 +        if allow_egress:
 +            EgressFireWallRule.create(
 +                apiclient=apiclient,
 +                networkid=virtual_machine.nic[0].networkid,
 +                protocol='All',
 +                cidrlist='0.0.0.0/0'
 +            )
 +        virtual_machine.ssh_ip = nat_rule.ipaddress
 +        virtual_machine.public_ip = nat_rule.ipaddress
 +
 +    @classmethod
 +    def create(cls, apiclient, services, templateid=None, accountid=None,
 +                    domainid=None, zoneid=None, networkids=None, serviceofferingid=None,
 +                    securitygroupids=None, projectid=None, startvm=None,
 +                    diskofferingid=None, affinitygroupnames=None, affinitygroupids=None, group=None,
-                     hostid=None, keypair=None, ipaddress=None, mode='default', method='GET',hypervisor=None):
++                    hostid=None, keypair=None, ipaddress=None, mode='default', method='GET',hypervisor=None,
++                    customcpunumber=None, customcpuspeed=None, custommemory=None, rootdisksize=None):
 +        """Create the instance"""
 +
 +        cmd = deployVirtualMachine.deployVirtualMachineCmd()
 +
 +        if serviceofferingid:
 +            cmd.serviceofferingid = serviceofferingid
 +        elif "serviceoffering" in services:
 +            cmd.serviceofferingid = services["serviceoffering"]
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        elif "zoneid" in services:
 +            cmd.zoneid = services["zoneid"]
 +        cmd.hypervisor = hypervisor
 +
 +        if "displayname" in services:
 +            cmd.displayname = services["displayname"]
 +
 +        if "name" in services:
 +            cmd.name = services["name"]
 +
 +        if accountid:
 +            cmd.account = accountid
 +        elif "account" in services:
 +            cmd.account = services["account"]
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +        elif "domainid" in services:
 +            cmd.domainid = services["domainid"]
 +
 +        if networkids:
 +            cmd.networkids = networkids
 +            allow_egress = False
 +        elif "networkids" in services:
 +            cmd.networkids = services["networkids"]
 +            allow_egress = False
 +        else:
 +            # When no networkids are passed, network
 +            # is created using the "defaultOfferingWithSourceNAT"
 +            # which has an egress policy of DENY. But guests in tests
 +            # need access to test network connectivity
 +            allow_egress = True
 +
 +        if templateid:
 +            cmd.templateid = templateid
 +        elif "template" in services:
 +            cmd.templateid = services["template"]
 +
 +        if diskofferingid:
 +            cmd.diskofferingid = diskofferingid
 +        elif "diskoffering" in services:
 +            cmd.diskofferingid = services["diskoffering"]
 +
 +        if keypair:
 +            cmd.keypair = keypair
 +        elif "keypair" in services:
 +            cmd.keypair = services["keypair"]
 +
 +        if ipaddress:
 +            cmd.ipaddress = ipaddress
 +        elif ipaddress in services:
 +            cmd.ipaddress = services["ipaddress"]
 +
 +        if securitygroupids:
 +            cmd.securitygroupids = [str(sg_id) for sg_id in securitygroupids]
 +
 +        if "affinitygroupnames" in services:
 +            cmd.affinitygroupnames  = services["affinitygroupnames"]
 +        elif affinitygroupnames:
 +            cmd.affinitygroupnames  = affinitygroupnames
 +
 +        if affinitygroupids:
 +            cmd.affinitygroupids  = affinitygroupids
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +
 +        if startvm is not None:
 +            cmd.startvm = startvm
 +
 +        if hostid:
 +            cmd.hostid = hostid
 +
 +        if "userdata" in services:
 +            cmd.userdata = base64.urlsafe_b64encode(services["userdata"])
 +
++        cmd.details = [{}]
++
++        if customcpunumber:
++            cmd.details[0]["cpuNumber"] = customcpunumber
++
++        if customcpuspeed:
++            cmd.details[0]["cpuSpeed"] = customcpuspeed
++
++        if custommemory:
++            cmd.details[0]["memory"] = custommemory
++
++        if rootdisksize >= 0:
++            cmd.details[0]["rootdisksize"] = rootdisksize
++
 +        if group:
 +            cmd.group = group
 +
 +        #program default access to ssh
 +        if mode.lower() == 'basic':
 +            cls.ssh_access_group(apiclient, cmd)
 +
 +        virtual_machine = apiclient.deployVirtualMachine(cmd, method=method)
 +
 +        virtual_machine.ssh_ip = virtual_machine.nic[0].ipaddress
 +        if startvm == False:
 +            virtual_machine.public_ip = virtual_machine.nic[0].ipaddress
 +            return VirtualMachine(virtual_machine.__dict__, services)
 +
 +        #program ssh access over NAT via PF
 +        if mode.lower() == 'advanced':
 +            cls.access_ssh_over_nat(apiclient, services, virtual_machine, allow_egress=allow_egress)
 +        elif mode.lower() == 'basic':
 +            if virtual_machine.publicip is not None:
 +                vm_ssh_ip = virtual_machine.publicip #EIP/ELB (netscaler) enabled zone
 +            else:
 +                vm_ssh_ip = virtual_machine.nic[0].ipaddress #regular basic zone with security group
 +            virtual_machine.ssh_ip = vm_ssh_ip
 +            virtual_machine.public_ip = vm_ssh_ip
 +
 +        return VirtualMachine(virtual_machine.__dict__, services)
 +
 +    def start(self, apiclient):
 +        """Start the instance"""
 +        cmd = startVirtualMachine.startVirtualMachineCmd()
 +        cmd.id = self.id
 +        apiclient.startVirtualMachine(cmd)
 +
 +    def stop(self, apiclient):
 +        """Stop the instance"""
 +        cmd = stopVirtualMachine.stopVirtualMachineCmd()
 +        cmd.id = self.id
 +        apiclient.stopVirtualMachine(cmd)
 +
 +    def reboot(self, apiclient):
 +        """Reboot the instance"""
 +        cmd = rebootVirtualMachine.rebootVirtualMachineCmd()
 +        cmd.id = self.id
 +        apiclient.rebootVirtualMachine(cmd)
 +
 +    def recover(self, apiclient):
 +        """Recover the instance"""
 +        cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
 +        cmd.id = self.id
 +        apiclient.recoverVirtualMachine(cmd)
 +
 +    def restore(self, apiclient, templateid=None):
 +        """Restore the instance"""
 +        cmd = restoreVirtualMachine.restoreVirtualMachineCmd()
 +        cmd.virtualmachineid = self.id
 +        if templateid:
 +            cmd.templateid = templateid
 +        return apiclient.restoreVirtualMachine(cmd)
 +
 +    def get_ssh_client(self, ipaddress=None, reconnect=False, port=None, keyPairFileLocation=None):
 +        """Get SSH object of VM"""
 +
 +        # If NAT Rules are not created while VM deployment in Advanced mode
 +        # then, IP address must be passed
 +        if ipaddress != None:
 +            self.ssh_ip = ipaddress
 +        if port:
 +            self.ssh_port = port
 +
 +        if keyPairFileLocation is not None:
 +            self.password = None
 +
 +        if reconnect:
 +            self.ssh_client = is_server_ssh_ready(
 +                                                    self.ssh_ip,
 +                                                    self.ssh_port,
 +                                                    self.username,
 +                                                    self.password,
 +                                                    keyPairFileLocation=keyPairFileLocation
 +                                                )
 +        self.ssh_client = self.ssh_client or is_server_ssh_ready(
 +                                                    self.ssh_ip,
 +                                                    self.ssh_port,
 +                                                    self.username,
 +                                                    self.password,
 +                                                    keyPairFileLocation=keyPairFileLocation
 +                                                )
 +        return self.ssh_client
 +
 +    def resetSshKey(self, apiclient, **kwargs):
 +        """Resets SSH key"""
 +
 +        cmd = resetSSHKeyForVirtualMachine.resetSSHKeyForVirtualMachineCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.resetSSHKeyForVirtualMachine(cmd))
 +
 +    def update(self, apiclient, **kwargs):
 +        """Updates the VM data"""
 +
 +        cmd = updateVirtualMachine.updateVirtualMachineCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.updateVirtualMachine(cmd))
 +
 +    def delete(self, apiclient):
 +        """Destroy an Instance"""
 +        cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
 +        cmd.id = self.id
 +        apiclient.destroyVirtualMachine(cmd)
 +
 +    def migrate(self, apiclient, hostid=None):
 +        """migrate an Instance"""
 +        cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
 +        cmd.virtualmachineid = self.id
 +        if hostid:
 +            cmd.hostid = hostid
 +        apiclient.migrateVirtualMachine(cmd)
 +
 +    def attach_volume(self, apiclient, volume):
 +        """Attach volume to instance"""
 +        cmd = attachVolume.attachVolumeCmd()
 +        cmd.id = volume.id
 +        cmd.virtualmachineid = self.id
 +        return apiclient.attachVolume(cmd)
 +
 +    def detach_volume(self, apiclient, volume):
 +        """Detach volume to instance"""
 +        cmd = detachVolume.detachVolumeCmd()
 +        cmd.id = volume.id
 +        return apiclient.detachVolume(cmd)
 +
 +    def add_nic(self, apiclient, networkId, ipaddress=None):
 +        """Add a NIC to a VM"""
 +        cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd()
 +        cmd.virtualmachineid = self.id
 +        cmd.networkid = networkId
 +
 +        if ipaddress:
 +            cmd.ipaddress = ipaddress
 +
 +        return apiclient.addNicToVirtualMachine(cmd)
 +
 +    def remove_nic(self, apiclient, nicId):
 +        """Remove a NIC to a VM"""
 +        cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd()
 +        cmd.nicid = nicId
 +        cmd.virtualmachineid = self.id
 +        return apiclient.removeNicFromVirtualMachine(cmd)
 +
 +    def update_default_nic(self, apiclient, nicId):
 +        """Set a NIC to be the default network adapter for a VM"""
 +        cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd()
 +        cmd.nicid = nicId
 +        cmd.virtualmachineid = self.id
 +        return apiclient.updateDefaultNicForVirtualMachine(cmd)
 +
 +    def attach_iso(self, apiclient, iso):
 +        """Attach ISO to instance"""
 +        cmd = attachIso.attachIsoCmd()
 +        cmd.id = iso.id
 +        cmd.virtualmachineid = self.id
 +        return apiclient.attachIso(cmd)
 +
 +    def detach_iso(self, apiclient):
 +        """Detach ISO to instance"""
 +        cmd = detachIso.detachIsoCmd()
 +        cmd.id = self.id
 +        return apiclient.detachIso(cmd)
 +
 +    def change_service_offering(self, apiclient, serviceOfferingId):
 +        """Change service offering of the instance"""
 +        cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
 +        cmd.id = self.id
 +        cmd.serviceofferingid = serviceOfferingId
 +        return apiclient.changeServiceForVirtualMachine(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all VMs matching criteria"""
 +
 +        cmd = listVirtualMachines.listVirtualMachinesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listVirtualMachines(cmd))
 +
 +    def resetPassword(self, apiclient):
 +        """Resets VM password if VM created using password enabled template"""
 +
 +        cmd = resetPasswordForVirtualMachine.resetPasswordForVirtualMachineCmd()
 +        cmd.id = self.id
 +        try:
 +            response = apiclient.resetPasswordForVirtualMachine(cmd)
 +        except Exception as e:
 +            raise Exception("Reset Password failed! - %s" % e)
 +        if response is not None:
 +            return response.password
 +
 +    def assign_virtual_machine(self, apiclient, account, domainid):
 +        """Move a user VM to another user under same domain."""
 +
 +        cmd                  = assignVirtualMachine.assignVirtualMachineCmd()
 +        cmd.virtualmachineid = self.id
 +        cmd.account          = account
 +        cmd.domainid         = domainid
 +        try:
 +            response = apiclient.assignVirtualMachine(cmd)
 +            return response
 +        except Exception as e:
 +            raise Exception("assignVirtualMachine failed - %s" %e)
 +
 +    def update_affinity_group(self, apiclient, affinitygroupids=None,
 +                              affinitygroupnames=None):
 +        """Update affinity group of a VM"""
 +        cmd = updateVMAffinityGroup.updateVMAffinityGroupCmd()
 +        cmd.id = self.id
 +
 +        if affinitygroupids:
 +            cmd.affinitygroupids = affinitygroupids
 +
 +        if affinitygroupnames:
 +            cmd.affinitygroupnames = affinitygroupnames
 +
 +        return apiclient.updateVMAffinityGroup(cmd)
 +
++    def scale(self, apiclient, serviceOfferingId,
++            customcpunumber=None, customcpuspeed=None, custommemory=None):
++        """Change service offering of the instance"""
++        cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
++        cmd.id = self.id
++        cmd.serviceofferingid = serviceOfferingId
++        cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}]
++        if customcpunumber:
++            cmd.details[0]["cpuNumber"] = customcpunumber
++        if customcpuspeed:
++            cmd.details[0]["cpuSpeed"] = customcpuspeed
++        if custommemory:
++            cmd.details[0]["memory"] = custommemory
++        return apiclient.scaleVirtualMachine(cmd)
++
 +
 +class Volume:
 +    """Manage Volume Life cycle
 +    """
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, zoneid=None, account=None,
 +               domainid=None, diskofferingid=None, projectid=None):
 +        """Create Volume"""
 +        cmd = createVolume.createVolumeCmd()
 +        cmd.name = services["diskname"]
 +
 +        if diskofferingid:
 +            cmd.diskofferingid = diskofferingid
 +        elif "diskofferingid" in services:
 +            cmd.diskofferingid = services["diskofferingid"]
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        elif "zoneid" in services:
 +            cmd.zoneid = services["zoneid"]
 +
 +        if account:
 +            cmd.account = account
 +        elif "account" in services:
 +            cmd.account = services["account"]
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +        elif "domainid" in services:
 +            cmd.domainid = services["domainid"]
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +        return Volume(apiclient.createVolume(cmd).__dict__)
 +
 +    @classmethod
 +    def create_custom_disk(cls, apiclient, services, account=None,
 +                                    domainid=None, diskofferingid=None):
 +        """Create Volume from Custom disk offering"""
 +        cmd = createVolume.createVolumeCmd()
 +        cmd.name = services["diskname"]
 +
 +        if diskofferingid:
 +            cmd.diskofferingid = diskofferingid
 +        elif "customdiskofferingid" in services:
 +            cmd.diskofferingid = services["customdiskofferingid"]
 +
 +        cmd.size = services["customdisksize"]
 +        cmd.zoneid = services["zoneid"]
 +
 +        if account:
 +            cmd.account = account
 +        else:
 +            cmd.account = services["account"]
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +        else:
 +            cmd.domainid = services["domainid"]
 +
 +        return Volume(apiclient.createVolume(cmd).__dict__)
 +
 +    @classmethod
 +    def create_from_snapshot(cls, apiclient, snapshot_id, services,
 +                             account=None, domainid=None):
 +        """Create Volume from snapshot"""
 +        cmd = createVolume.createVolumeCmd()
 +        cmd.name = "-".join([services["diskname"], random_gen()])
 +        cmd.snapshotid = snapshot_id
 +        cmd.zoneid = services["zoneid"]
 +        cmd.size = services["size"]
 +        if account:
 +            cmd.account = account
 +        else:
 +            cmd.account = services["account"]
 +        if domainid:
 +            cmd.domainid = domainid
 +        else:
 +            cmd.domainid = services["domainid"]
 +        return Volume(apiclient.createVolume(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Volume"""
 +        cmd = deleteVolume.deleteVolumeCmd()
 +        cmd.id = self.id
 +        apiclient.deleteVolume(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all volumes matching criteria"""
 +
 +        cmd = listVolumes.listVolumesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listVolumes(cmd))
 +
 +    def resize(self, apiclient, **kwargs):
 +        """Resize a volume"""
 +        cmd = resizeVolume.resizeVolumeCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.resizeVolume(cmd))
 +
 +    @classmethod
 +    def upload(cls, apiclient, services, zoneid=None, account=None, domainid=None, url=None):
 +        """Uploads the volume to specified account"""
 +
 +        cmd = uploadVolume.uploadVolumeCmd()
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        if account:
 +            cmd.account = account
 +        if domainid:
 +            cmd.domainid = domainid
 +        cmd.format = services["format"]
 +        cmd.name = services["diskname"]
 +        if url:
 +            cmd.url = url
 +        else:
 +            cmd.url = services["url"]
 +        return Volume(apiclient.uploadVolume(cmd).__dict__)
 +
 +    def wait_for_upload(self, apiclient, timeout=10, interval=60):
 +        """Wait for upload"""
 +        # Sleep to ensure template is in proper state before download
 +        time.sleep(interval)
 +
 +        while True:
 +            volume_response = Volume.list(
 +                                    apiclient,
 +                                    id=self.id,
 +                                    zoneid=self.zoneid,
 +                                    )
 +            if isinstance(volume_response, list):
 +
 +                volume = volume_response[0]
 +                # If volume is ready,
 +                # volume.state = Allocated
 +                if volume.state == 'Uploaded':
 +                    break
 +
 +                elif 'Uploading' in volume.state:
 +                    time.sleep(interval)
 +
 +                elif 'Installing' not in volume.state:
 +                    raise Exception(
 +                        "Error in uploading volume: status - %s" %
 +                                                            volume.state)
 +            elif timeout == 0:
 +                break
 +
 +            else:
 +                time.sleep(interval)
 +                timeout = timeout - 1
 +        return
 +
 +    @classmethod
 +    def migrate(cls, apiclient, **kwargs):
 +        """Migrate a volume"""
 +        cmd = migrateVolume.migrateVolumeCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.migrateVolume(cmd))
 +
 +class Snapshot:
 +    """Manage Snapshot Lifecycle
 +    """
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, volume_id, account=None,
 +                                            domainid=None, projectid=None):
 +        """Create Snapshot"""
 +        cmd = createSnapshot.createSnapshotCmd()
 +        cmd.volumeid = volume_id
 +        if account:
 +            cmd.account = account
 +        if domainid:
 +            cmd.domainid = domainid
 +        if projectid:
 +            cmd.projectid = projectid
 +        return Snapshot(apiclient.createSnapshot(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Snapshot"""
 +        cmd = deleteSnapshot.deleteSnapshotCmd()
 +        cmd.id = self.id
 +        apiclient.deleteSnapshot(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all snapshots matching criteria"""
 +
 +        cmd = listSnapshots.listSnapshotsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listSnapshots(cmd))
 +
 +
 +class Template:
 +    """Manage template life cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, volumeid=None,
 +               account=None, domainid=None, projectid=None):
 +        """Create template from Volume"""
 +        # Create template from Virtual machine and Volume ID
 +        cmd = createTemplate.createTemplateCmd()
 +        cmd.displaytext = services["displaytext"]
 +        cmd.name = "-".join([services["name"], random_gen()])
 +        if "ostypeid" in services:
 +            cmd.ostypeid = services["ostypeid"]
 +        elif "ostype" in services:
 +            # Find OSTypeId from Os type
 +            sub_cmd = listOsTypes.listOsTypesCmd()
 +            sub_cmd.description = services["ostype"]
 +            ostypes = apiclient.listOsTypes(sub_cmd)
 +
 +            if not isinstance(ostypes, list):
 +                raise Exception(
 +                    "Unable to find Ostype id with desc: %s" %
 +                                                services["ostype"])
 +            cmd.ostypeid = ostypes[0].id
 +        else:
 +            raise Exception(
 +                    "Unable to find Ostype is required for creating template")
 +
 +        cmd.isfeatured = services["isfeatured"] if "isfeatured" in services else False
 +        cmd.ispublic = services["ispublic"] if "ispublic" in services else False
 +        cmd.isextractable = services["isextractable"] if "isextractable" in services else False
 +        cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False
 +
 +        if volumeid:
 +            cmd.volumeid = volumeid
 +
 +        if account:
 +            cmd.account = account
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +        return Template(apiclient.createTemplate(cmd).__dict__)
 +
 +    @classmethod
 +    def register(cls, apiclient, services, zoneid=None,
 +                                                account=None, domainid=None, hypervisor=None):
 +        """Create template from URL"""
 +
 +        # Create template from Virtual machine and Volume ID
 +        cmd = registerTemplate.registerTemplateCmd()
 +        cmd.displaytext = services["displaytext"]
 +        cmd.name = "-".join([services["name"], random_gen()])
 +        cmd.format = services["format"]
 +        cmd.hypervisor = hypervisor 
 +
 +        if "ostypeid" in services:
 +            cmd.ostypeid = services["ostypeid"]
 +        elif "ostype" in services:
 +            # Find OSTypeId from Os type
 +            sub_cmd = listOsTypes.listOsTypesCmd()
 +            sub_cmd.description = services["ostype"]
 +            ostypes = apiclient.listOsTypes(sub_cmd)
 +
 +            if not isinstance(ostypes, list):
 +                raise Exception(
 +                    "Unable to find Ostype id with desc: %s" %
 +                                                services["ostype"])
 +            cmd.ostypeid = ostypes[0].id
 +        else:
 +            raise Exception(
 +                    "Unable to find Ostype is required for registering template")
 +
 +        cmd.url = services["url"]
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        else:
 +            cmd.zoneid = services["zoneid"]
 +
 +        cmd.isfeatured = services["isfeatured"] if "isfeatured" in services else False
 +        cmd.ispublic = services["ispublic"] if "ispublic" in services else False
 +        cmd.isextractable = services["isextractable"] if "isextractable" in services else False
 +        cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False
 +
 +        if account:
 +            cmd.account = account
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +
 +        # Register Template
 +        template = apiclient.registerTemplate(cmd)
 +
 +        if isinstance(template, list):
 +            return Template(template[0].__dict__)
 +
 +    @classmethod
 +    def extract(cls, apiclient, id, mode, zoneid=None):
 +        "Extract template "
 +
 +        cmd = extractTemplate.extractTemplateCmd()
 +        cmd.id = id
 +        cmd.mode = mode
 +        cmd.zoneid = zoneid
 +
 +        return apiclient.extractTemplate(cmd)
 +
 +    @classmethod
 +    def create_from_snapshot(cls, apiclient, snapshot, services,
 +                                                        random_name=True):
 +        """Create Template from snapshot"""
 +        # Create template from Virtual machine and Snapshot ID
 +        cmd = createTemplate.createTemplateCmd()
 +        cmd.displaytext = services["displaytext"]
 +        cmd.name = "-".join([
 +                             services["name"],
 +                             random_gen()
 +                            ]) if random_name else services["name"]
 +
 +        if "ostypeid" in services:
 +            cmd.ostypeid = services["ostypeid"]
 +        elif "ostype" in services:
 +            # Find OSTypeId from Os type
 +            sub_cmd = listOsTypes.listOsTypesCmd()
 +            sub_cmd.description = services["ostype"]
 +            ostypes = apiclient.listOsTypes(sub_cmd)
 +
 +            if not isinstance(ostypes, list):
 +                raise Exception(
 +                    "Unable to find Ostype id with desc: %s" %
 +                                                services["ostype"])
 +            cmd.ostypeid = ostypes[0].id
 +        else:
 +            raise Exception(
 +                    "Unable to find Ostype is required for creating template")
 +
 +        cmd.snapshotid = snapshot.id
 +        return Template(apiclient.createTemplate(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Template"""
 +
 +        cmd = deleteTemplate.deleteTemplateCmd()
 +        cmd.id = self.id
 +        apiclient.deleteTemplate(cmd)
 +
 +    def download(self, apiclient, timeout=5, interval=60):
 +        """Download Template"""
 +        # Sleep to ensure template is in proper state before download
 +        time.sleep(interval)
 +
 +        while True:
 +            template_response = Template.list(
 +                                    apiclient,
 +                                    id=self.id,
 +                                    zoneid=self.zoneid,
 +                                    templatefilter='self'
 +                                    )
 +            if isinstance(template_response, list):
 +
 +                template = template_response[0]
 +                # If template is ready,
 +                # template.status = Download Complete
 +                # Downloading - x% Downloaded
 +                # Error - Any other string
 +                if template.status == 'Download Complete':
 +                    break
 +
 +                elif 'Downloaded' in template.status:
 +                    time.sleep(interval)
 +
 +                elif 'Installing' not in template.status:
 +                    raise Exception(
 +                        "Error in downloading template: status - %s" %
 +                                                            template.status)
 +
 +            elif timeout == 0:
 +                break
 +
 +            else:
 +                time.sleep(interval)
 +                timeout = timeout - 1
 +        return
 +
 +    def updatePermissions(self, apiclient, **kwargs):
 +        """Updates the template permissions"""
 +
 +        cmd = updateTemplatePermissions.updateTemplatePermissionsCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.updateTemplatePermissions(cmd))
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all templates matching criteria"""
 +
 +        cmd = listTemplates.listTemplatesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listTemplates(cmd))
 +
 +
 +class Iso:
 +    """Manage ISO life cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, account=None, domainid=None,
 +                                                        projectid=None):
 +        """Create an ISO"""
 +        # Create ISO from URL
 +        cmd = registerIso.registerIsoCmd()
 +        cmd.displaytext = services["displaytext"]
 +        cmd.name = services["name"]
 +        if "ostypeid" in services:
 +            cmd.ostypeid = services["ostypeid"]
 +        elif "ostype" in services:
 +            # Find OSTypeId from Os type
 +            sub_cmd = listOsTypes.listOsTypesCmd()
 +            sub_cmd.description = services["ostype"]
 +            ostypes = apiclient.listOsTypes(sub_cmd)
 +
 +            if not isinstance(ostypes, list):
 +                raise Exception(
 +                    "Unable to find Ostype id with desc: %s" %
 +                                                services["ostype"])
 +            cmd.ostypeid = ostypes[0].id
 +        else:
 +            raise Exception(
 +                    "Unable to find Ostype is required for creating ISO")
 +
 +        cmd.url = services["url"]
 +        cmd.zoneid = services["zoneid"]
 +
 +        if "isextractable" in services:
 +            cmd.isextractable = services["isextractable"]
 +        if "isfeatured" in services:
 +            cmd.isfeatured = services["isfeatured"]
 +        if "ispublic" in services:
 +            cmd.ispublic = services["ispublic"]
 +
 +        if account:
 +            cmd.account = account
 +        if domainid:
 +            cmd.domainid = domainid
 +        if projectid:
 +            cmd.projectid = projectid
 +        # Register ISO
 +        iso = apiclient.registerIso(cmd)
 +
 +        if iso:
 +            return Iso(iso[0].__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete an ISO"""
 +        cmd = deleteIso.deleteIsoCmd()
 +        cmd.id = self.id
 +        apiclient.deleteIso(cmd)
 +        return
 +
 +    def download(self, apiclient, timeout=5, interval=60):
 +        """Download an ISO"""
 +        # Ensuring ISO is successfully downloaded
 +        while True:
 +            time.sleep(interval)
 +
 +            cmd = listIsos.listIsosCmd()
 +            cmd.id = self.id
 +            iso_response = apiclient.listIsos(cmd)
 +
 +            if isinstance(iso_response, list):
 +                response = iso_response[0]
 +                # Again initialize timeout to avoid listISO failure
 +                timeout = 5
 +                # Check whether download is in progress(for Ex:10% Downloaded)
 +                # or ISO is 'Successfully Installed'
 +                if response.status == 'Successfully Installed':
 +                    return
 +                elif 'Downloaded' not in response.status and \
 +                    'Installing' not in response.status:
 +                    raise Exception(
 +                        "Error In Downloading ISO: ISO Status - %s" %
 +                                                            response.status)
 +
 +            elif timeout == 0:
 +                raise Exception("ISO download Timeout Exception")
 +            else:
 +                timeout = timeout - 1
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists all available ISO files."""
 +
 +        cmd = listIsos.listIsosCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listIsos(cmd))
 +
 +
 +class PublicIPAddress:
 +    """Manage Public IP Addresses"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, accountid=None, zoneid=None, domainid=None, services=None,
 +               networkid=None, projectid=None, vpcid=None, isportable=False):
 +        """Associate Public IP address"""
 +        cmd = associateIpAddress.associateIpAddressCmd()
 +
 +        if accountid:
 +            cmd.account = accountid
 +        elif "account" in services:
 +            cmd.account = services["account"]
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        elif "zoneid" in services:
 +            cmd.zoneid = services["zoneid"]
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +        elif "domainid" in services:
 +            cmd.domainid = services["domainid"]
 +
 +        if isportable:
 +            cmd.isportable = isportable
 +
 +        if networkid:
 +            cmd.networkid = networkid
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +
 +        if vpcid:
 +            cmd.vpcid = vpcid
 +        return PublicIPAddress(apiclient.associateIpAddress(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Dissociate Public IP address"""
 +        cmd = disassociateIpAddress.disassociateIpAddressCmd()
 +        cmd.id = self.ipaddress.id
 +        apiclient.disassociateIpAddress(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Public IPs matching criteria"""
 +
 +        cmd = listPublicIpAddresses.listPublicIpAddressesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listPublicIpAddresses(cmd))
 +
 +
 +class NATRule:
 +    """Manage port forwarding rule"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, virtual_machine, services, ipaddressid=None,
-                projectid=None, openfirewall=False, networkid=None, vpcid=None):
++               projectid=None, openfirewall=False, networkid=None, vpcid=None,
++               vmguestip=None):
 +        """Create Port forwarding rule"""
 +        cmd = createPortForwardingRule.createPortForwardingRuleCmd()
 +
 +        if ipaddressid:
 +            cmd.ipaddressid = ipaddressid
 +        elif "ipaddressid" in services:
 +            cmd.ipaddressid = services["ipaddressid"]
 +
 +        cmd.privateport = services["privateport"]
 +        cmd.publicport = services["publicport"]
 +        if "privateendport" in services:
 +            cmd.privateendport = services["privateendport"]
 +        if "publicendport" in services:
 +            cmd.publicendport = services["publicendport"]
 +        cmd.protocol = services["protocol"]
 +        cmd.virtualmachineid = virtual_machine.id
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +
 +        if openfirewall:
 +            cmd.openfirewall = True
 +
 +        if networkid:
 +            cmd.networkid = networkid
 +
 +        if vpcid:
 +            cmd.vpcid = vpcid
++
++        if vmguestip:
++            cmd.vmguestip = vmguestip
++
 +        return NATRule(apiclient.createPortForwardingRule(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete port forwarding"""
 +        cmd = deletePortForwardingRule.deletePortForwardingRuleCmd()
 +        cmd.id = self.id
 +        apiclient.deletePortForwardingRule(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all NAT rules matching criteria"""
 +
 +        cmd = listPortForwardingRules.listPortForwardingRulesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listPortForwardingRules(cmd))
 +
 +
 +class StaticNATRule:
 +    """Manage Static NAT rule"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, ipaddressid=None, networkid=None, vpcid=None):
 +        """Creates static ip forwarding rule"""
 +
 +        cmd = createFirewallRule.createFirewallRuleCmd()
 +        cmd.protocol = services["protocol"]
 +        cmd.startport = services["startport"]
 +
 +        if "endport" in services:
 +            cmd.endport = services["endport"]
 +
 +        if "cidrlist" in services:
 +            cmd.cidrlist = services["cidrlist"]
 +
 +        if ipaddressid:
 +            cmd.ipaddressid = ipaddressid
 +        elif "ipaddressid" in services:
 +            cmd.ipaddressid = services["ipaddressid"]
 +
 +        if networkid:
 +            cmd.networkid = networkid
 +
 +        if vpcid:
 +            cmd.vpcid = vpcid
 +        return StaticNATRule(apiclient.createFirewallRule(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete IP forwarding rule"""
 +        cmd = deleteIpForwardingRule.deleteIpForwardingRuleCmd()
 +        cmd.id = self.id
 +        apiclient.deleteIpForwardingRule(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all IP forwarding rules matching criteria"""
 +
 +        cmd = listIpForwardingRules.listIpForwardingRulesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listIpForwardingRules(cmd))
 +
 +    @classmethod
-     def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None):
++    def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None,
++            vmguestip=None):
 +        """Enables Static NAT rule"""
 +
 +        cmd = enableStaticNat.enableStaticNatCmd()
 +        cmd.ipaddressid = ipaddressid
 +        cmd.virtualmachineid = virtualmachineid
 +        if networkid:
 +            cmd.networkid = networkid
++
++        if vmguestip:
++            cmd.vmguestip = vmguestip
 +        apiclient.enableStaticNat(cmd)
 +        return
 +
 +    @classmethod
 +    def disable(cls, apiclient, ipaddressid, virtualmachineid):
 +        """Disables Static NAT rule"""
 +
 +        cmd = disableStaticNat.disableStaticNatCmd()
 +        cmd.ipaddressid = ipaddressid
 +        apiclient.disableStaticNat(cmd)
 +        return
 +
 +
 +class EgressFireWallRule:
 +    """Manage Egress Firewall rule"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, networkid, protocol, cidrlist=None,
 +               startport=None, endport=None):
 +        """Create Egress Firewall Rule"""
 +        cmd = createEgressFirewallRule.createEgressFirewallRuleCmd()
 +        cmd.networkid = networkid
 +        cmd.protocol = protocol
 +        if cidrlist:
 +            cmd.cidrlist = cidrlist
 +        if startport:
 +            cmd.startport = startport
 +        if endport:
 +            cmd.endport = endport
 +
 +        return EgressFireWallRule(apiclient.createEgressFirewallRule(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Egress Firewall rule"""
 +        cmd = deleteEgressFirewallRule.deleteEgressFirewallRuleCmd()
 +        cmd.id = self.id
 +        apiclient.deleteEgressFirewallRule(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Egress Firewall Rules matching criteria"""
 +
 +        cmd = listEgressFirewallRules.listEgressFirewallRulesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listEgressFirewallRules(cmd))
 +
 +
 +
 +class FireWallRule:
 +    """Manage Firewall rule"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, ipaddressid, protocol, cidrlist=None,
 +               startport=None, endport=None, projectid=None, vpcid=None):
 +        """Create Firewall Rule"""
 +        cmd = createFirewallRule.createFirewallRuleCmd()
 +        cmd.ipaddressid = ipaddressid
 +        cmd.protocol = protocol
 +        if cidrlist:
 +            cmd.cidrlist = cidrlist
 +        if startport:
 +            cmd.startport = startport
 +        if endport:
 +            cmd.endport = endport
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +
 +        if vpcid:
 +            cmd.vpcid = vpcid
 +
 +        return FireWallRule(apiclient.createFirewallRule(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Firewall rule"""
 +        cmd = deleteFirewallRule.deleteFirewallRuleCmd()
 +        cmd.id = self.id
 +        apiclient.deleteFirewallRule(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Firewall Rules matching criteria"""
 +
 +        cmd = listFirewallRules.listFirewallRulesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listFirewallRules(cmd))
 +
 +
 +class ServiceOffering:
 +    """Manage service offerings cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, domainid=None, **kwargs):
 +        """Create Service offering"""
 +        cmd = createServiceOffering.createServiceOfferingCmd()
 +        cmd.cpunumber = services["cpunumber"]
 +        cmd.cpuspeed = services["cpuspeed"]
 +        cmd.displaytext = services["displaytext"]
 +        cmd.memory = services["memory"]
 +        cmd.name = services["name"]
 +        if "storagetype" in services:
 +            cmd.storagetype = services["storagetype"]
 +
 +        if "systemvmtype" in services:
 +            cmd.systemvmtype = services['systemvmtype']
 +
 +        if "issystem" in services:
 +            cmd.issystem = services['issystem']
 +
 +        if "tags" in services:
 +            cmd.tags = services["tags"]
 +
 +        if "deploymentplanner" in services:
 +            cmd.deploymentplanner = services["deploymentplanner"]
 +
++        if "serviceofferingdetails" in services:
++            cmd.serviceofferingdetails.append({services['serviceofferingdetails']})
++
 +        if "isvolatile" in services:
 +            cmd.isvolatile = services["isvolatile"]
 +
 +        # Service Offering private to that domain
 +        if domainid:
 +            cmd.domainid = domainid
 +
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return ServiceOffering(apiclient.createServiceOffering(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Service offering"""
 +        cmd = deleteServiceOffering.deleteServiceOfferingCmd()
 +        cmd.id = self.id
 +        apiclient.deleteServiceOffering(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists all available service offerings."""
 +
 +        cmd = listServiceOfferings.listServiceOfferingsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listServiceOfferings(cmd))
 +
 +
 +class DiskOffering:
 +    """Manage disk offerings cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, custom=False, domainid=None):
 +        """Create Disk offering"""
 +        cmd = createDiskOffering.createDiskOfferingCmd()
 +        cmd.displaytext = services["displaytext"]
 +        cmd.name = services["name"]
 +        if custom:
 +            cmd.customized = True
 +        else:
 +            cmd.disksize = services["disksize"]
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +
 +        if "storagetype" in services:
 +            cmd.storagetype = services["storagetype"]
 +
 +        return DiskOffering(apiclient.createDiskOffering(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Disk offering"""
 +        cmd = deleteDiskOffering.deleteDiskOfferingCmd()
 +        cmd.id = self.id
 +        apiclient.deleteDiskOffering(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists all available disk offerings."""
 +
 +        cmd = listDiskOfferings.listDiskOfferingsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listDiskOfferings(cmd))
 +
 +
 +class NetworkOffering:
 +    """Manage network offerings cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, **kwargs):
 +        """Create network offering"""
 +
 +        cmd = createNetworkOffering.createNetworkOfferingCmd()
 +        cmd.displaytext = "-".join([services["displaytext"], random_gen()])
 +        cmd.name = "-".join([services["name"], random_gen()])
 +        cmd.guestiptype = services["guestiptype"]
 +        cmd.supportedservices = ''
 +        if "supportedservices" in services:
 +            cmd.supportedservices = services["supportedservices"]
 +        cmd.traffictype = services["traffictype"]
 +
 +        if "useVpc" in services:
 +            cmd.useVpc = services["useVpc"]
 +        cmd.serviceproviderlist = []
 +        if "serviceProviderList" in services:
 +            for service, provider in services["serviceProviderList"].items():
 +                cmd.serviceproviderlist.append({
 +                                            'service': service,
 +                                            'provider': provider
 +                                           })
 +        if "serviceCapabilityList" in services:
 +            cmd.servicecapabilitylist = []
 +            for service, capability in services["serviceCapabilityList"].items():
 +                for ctype, value in capability.items():
 +                    cmd.servicecapabilitylist.append({
 +                                            'service': service,
 +                                            'capabilitytype': ctype,
 +                                            'capabilityvalue': value
 +                                           })
 +        if "specifyVlan" in services:
 +            cmd.specifyVlan = services["specifyVlan"]
 +        if "specifyIpRanges" in services:
 +            cmd.specifyIpRanges = services["specifyIpRanges"]
 +        if "ispersistent" in services:
 +            cmd.ispersistent = services["ispersistent"]
 +        if "egress_policy" in services:
 +            cmd.egressdefaultpolicy = services["egress_policy"]
 +
 +        cmd.availability = 'Optional'
 +
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +
 +        return NetworkOffering(apiclient.createNetworkOffering(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete network offering"""
 +        cmd = deleteNetworkOffering.deleteNetworkOfferingCmd()
 +        cmd.id = self.id
 +        apiclient.deleteNetworkOffering(cmd)
 +        return
 +
 +    def update(self, apiclient, **kwargs):
 +        """Lists all available network offerings."""
 +
 +        cmd = updateNetworkOffering.updateNetworkOfferingCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.updateNetworkOffering(cmd))
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists all available network offerings."""
 +
 +        cmd = listNetworkOfferings.listNetworkOfferingsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listNetworkOfferings(cmd))
 +
 +
 +class SnapshotPolicy:
 +    """Manage snapshot policies"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, volumeid, services):
 +        """Create Snapshot policy"""
 +        cmd = createSnapshotPolicy.createSnapshotPolicyCmd()
 +        cmd.intervaltype = services["intervaltype"]
 +        cmd.maxsnaps = services["maxsnaps"]
 +        cmd.schedule = services["schedule"]
 +        cmd.timezone = services["timezone"]
 +        cmd.volumeid = volumeid
 +        return SnapshotPolicy(apiclient.createSnapshotPolicy(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Snapshot policy"""
 +        cmd = deleteSnapshotPolicies.deleteSnapshotPoliciesCmd()
 +        cmd.id = self.id
 +        apiclient.deleteSnapshotPolicies(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists snapshot policies."""
 +
 +        cmd = listSnapshotPolicies.listSnapshotPoliciesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listSnapshotPolicies(cmd))
 +
 +
 +class LoadBalancerRule:
 +    """Manage Load Balancer rule"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, ipaddressid=None, accountid=None,
 +               networkid=None, vpcid=None, projectid=None, domainid=None):
 +        """Create Load balancing Rule"""
 +
 +        cmd = createLoadBalancerRule.createLoadBalancerRuleCmd()
 +
 +        if ipaddressid:
 +            cmd.publicipid = ipaddressid
 +        elif "ipaddressid" in services:
 +            cmd.publicipid = services["ipaddressid"]
 +
 +        if accountid:
 +            cmd.account = accountid
 +        elif "account" in services:
 +            cmd.account = services["account"]
 +
 +        if domainid:
 +            cmd.domainid = domainid
 +
 +        if vpcid:
 +            cmd.vpcid = vpcid
 +        cmd.name = services["name"]
 +        cmd.algorithm = services["alg"]
 +        cmd.privateport = services["privateport"]
 +        cmd.publicport = services["publicport"]
 +
 +        if "openfirewall" in services:
 +            cmd.openfirewall = services["openfirewall"]
 +
 +        if projectid:
 +            cmd.projectid = projectid
 +
 +        if networkid:
 +            cmd.networkid = networkid
 +        return LoadBalancerRule(apiclient.createLoadBalancerRule(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete load balancing rule"""
 +        cmd = deleteLoadBalancerRule.deleteLoadBalancerRuleCmd()
 +        cmd.id = self.id
 +        apiclient.deleteLoadBalancerRule(cmd)
 +        return
 +
 +    def assign(self, apiclient, vms):
 +        """Assign virtual machines to load balancing rule"""
 +        cmd = assignToLoadBalancerRule.assignToLoadBalancerRuleCmd()
 +        cmd.id = self.id
 +        cmd.virtualmachineids = [str(vm.id) for vm in vms]
 +        apiclient.assignToLoadBalancerRule(cmd)
 +        return
 +
 +    def remove(self, apiclient, vms):
 +        """Remove virtual machines from load balancing rule"""
 +        cmd = removeFromLoadBalancerRule.removeFromLoadBalancerRuleCmd()
 +        cmd.id = self.id
 +        cmd.virtualmachineids = [str(vm.id) for vm in vms]
 +        apiclient.removeFromLoadBalancerRule(cmd)
 +        return
 +
 +    def update(self, apiclient, algorithm=None, description=None, name=None, **kwargs):
 +        """Updates the load balancing rule"""
 +        cmd = updateLoadBalancerRule.updateLoadBalancerRuleCmd()
 +        cmd.id = self.id
 +        if algorithm:
 +            cmd.algorithm = algorithm
 +        if description:
 +            cmd.description = description
 +        if name:
 +            cmd.name = name
 +
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return apiclient.updateLoadBalancerRule(cmd)
 +
 +    def createSticky(self, apiclient, methodname, name, description=None, param=None):
 +        """Creates a sticky policy for the LB rule"""
 +
 +        cmd = createLBStickinessPolicy.createLBStickinessPolicyCmd()
 +        cmd.lbruleid = self.id
 +        cmd.methodname = methodname
 +        cmd.name = name
 +        if description:
 +            cmd.description = description
 +        if param:
 +            cmd.param = []
 +            for name, value in param.items():
 +                cmd.param.append({'name': name, 'value': value})
 +        return apiclient.createLBStickinessPolicy(cmd)
 +
 +    def deleteSticky(self, apiclient, id):
 +        """Deletes stickyness policy"""
 +
 +        cmd = deleteLBStickinessPolicy.deleteLBStickinessPolicyCmd()
 +        cmd.id = id
 +        return apiclient.deleteLBStickinessPolicy(cmd)
 +
 +    @classmethod
 +    def listStickyPolicies(cls, apiclient, lbruleid, **kwargs):
 +        """Lists stickiness policies for load balancing rule"""
 +
 +        cmd = listLBStickinessPolicies.listLBStickinessPoliciesCmd()
 +        cmd.lbruleid = lbruleid
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return apiclient.listLBStickinessPolicies(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Load balancing rules matching criteria"""
 +
 +        cmd = listLoadBalancerRules.listLoadBalancerRulesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listLoadBalancerRules(cmd))
 +
 +
 +class Cluster:
 +    """Manage Cluster life cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, zoneid=None, podid=None, hypervisor=None):
 +        """Create Cluster"""
 +        cmd = addCluster.addClusterCmd()
 +        cmd.clustertype = services["clustertype"]
 +        cmd.hypervisor = hypervisor
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        else:
 +            cmd.zoneid = services["zoneid"]
 +
 +        if podid:
 +            cmd.podid = podid
 +        else:
 +            cmd.podid = services["podid"]
 +
 +        if "username" in services:
 +            cmd.username = services["username"]
 +        if "password" in services:
 +            cmd.password = services["password"]
 +        if "url" in services:
 +            cmd.url = services["url"]
 +        if "clustername" in services:
 +            cmd.clustername = services["clustername"]
 +
 +        return Cluster(apiclient.addCluster(cmd)[0].__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Cluster"""
 +        cmd = deleteCluster.deleteClusterCmd()
 +        cmd.id = self.id
 +        apiclient.deleteCluster(cmd)
 +        return
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Clusters matching criteria"""
 +
 +        cmd = listClusters.listClustersCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listClusters(cmd))
 +
 +
 +class Host:
 +    """Manage Host life cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, cluster, services, zoneid=None, podid=None, hypervisor=None):
 +        """
 +        1. Creates the host based upon the information provided.
 +        2. Verifies the output of the adding host and its state post addition
 +           Returns FAILED in case of an issue, else an instance of Host
 +        """
 +        try:
 +            cmd = addHost.addHostCmd()
 +            cmd.hypervisor = hypervisor
 +            cmd.url = services["url"]
 +            cmd.clusterid = cluster.id
 +
 +            if zoneid:
 +                cmd.zoneid = zoneid
 +            else:
 +                cmd.zoneid = services["zoneid"]
 +
 +            if podid:
 +                cmd.podid = podid
 +            else:
 +                cmd.podid = services["podid"]
 +
 +            if "clustertype" in services:
 +                cmd.clustertype = services["clustertype"]
 +            if "username" in services:
 +                cmd.username = services["username"]
 +            if "password" in services:
 +                cmd.password = services["password"]
 +
 +            '''
 +            Adds a Host,
 +            If response is valid and host is up return
 +            an instance of Host.
 +            If response is invalid, returns FAILED.
 +            If host state is not up, verify through listHosts call
 +            till host status is up and return accordingly. Max 3 retries
 +            '''
 +            host = apiclient.addHost(cmd)
 +            ret = validateList(host)
 +            if ret[0] == PASS:
 +                if str(host[0].state).lower() == 'up':
 +                    return Host(host[0].__dict__)
 +                retries = 3
 +                while retries:
 +                    lh_resp = apiclient.listHosts(host[0].id)
 +                    ret = validateList(lh_resp)
 +                    if (ret[0] == PASS) and (str(ret[1].state).lower() == 'up'):
 +                        return Host(host[0].__dict__)
 +                    retries += -1
 +            return FAILED
 +        except Exception, e:
 +            print "Exception Occurred Under Host.create : %s" % GetDetailExceptionInfo(e)
 +            return FAILED
 +
 +    def delete(self, apiclient):
 +        """Delete Host"""
 +        # Host must be in maintenance mode before deletion
 +        cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
 +        cmd.id = self.id
 +        apiclient.prepareHostForMaintenance(cmd)
 +        time.sleep(30)
 +
 +        cmd = deleteHost.deleteHostCmd()
 +        cmd.id = self.id
 +        apiclient.deleteHost(cmd)
 +        return
 +
 +    def enableMaintenance(self, apiclient):
 +        """enables maintenance mode Host"""
 +
 +        cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
 +        cmd.id = self.id
 +        return apiclient.prepareHostForMaintenance(cmd)
 +
 +    @classmethod
 +    def enableMaintenance(cls, apiclient, id):
 +        """enables maintenance mode Host"""
 +
 +        cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
 +        cmd.id = id
 +        return apiclient.prepareHostForMaintenance(cmd)
 +
 +    def cancelMaintenance(self, apiclient):
 +        """Cancels maintenance mode Host"""
 +
 +        cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
 +        cmd.id = self.id
 +        return apiclient.cancelHostMaintenance(cmd)
 +
 +    @classmethod
 +    def cancelMaintenance(cls, apiclient, id):
 +        """Cancels maintenance mode Host"""
 +
 +        cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
 +        cmd.id = id
 +        return apiclient.cancelHostMaintenance(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Hosts matching criteria"""
 +
 +        cmd = listHosts.listHostsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listHosts(cmd))
 +
 +    @classmethod
 +    def listForMigration(cls, apiclient, **kwargs):
 +        """List all Hosts for migration matching criteria"""
 +
 +        cmd = findHostsForMigration.findHostsForMigrationCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.findHostsForMigration(cmd))
 +
 +    @classmethod
 +    def update(cls, apiclient, **kwargs):
 +        """Update host information"""
 +
 +        cmd = updateHost.updateHostCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.updateHost(cmd))
 +
 +
 +class StoragePool:
 +    """Manage Storage pools (Primary Storage)"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, clusterid=None,
 +                                        zoneid=None, podid=None):
 +        """Create Storage pool (Primary Storage)"""
 +
 +        cmd = createStoragePool.createStoragePoolCmd()
 +        cmd.name = services["name"]
 +
 +        if podid:
 +            cmd.podid = podid
 +        else:
 +            cmd.podid = services["podid"]
 +
 +        cmd.url = services["url"]
 +        if clusterid:
 +            cmd.clusterid = clusterid
 +        elif "clusterid" in services:
 +            cmd.clusterid = services["clusterid"]
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        else:
 +            cmd.zoneid = services["zoneid"]
 +
 +        return StoragePool(apiclient.createStoragePool(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Storage pool (Primary Storage)"""
 +
 +        # Storage pool must be in maintenance mode before deletion
 +        cmd = enableStorageMaintenance.enableStorageMaintenanceCmd()
 +        cmd.id = self.id
 +        apiclient.enableStorageMaintenance(cmd)
 +        time.sleep(30)
 +        cmd = deleteStoragePool.deleteStoragePoolCmd()
 +        cmd.id = self.id
 +        apiclient.deleteStoragePool(cmd)
 +        return
 +
 +    def enableMaintenance(self, apiclient):
 +        """enables maintenance mode Storage pool"""
 +
 +        cmd = enableStorageMaintenance.enableStorageMaintenanceCmd()
 +        cmd.id = self.id
 +        return apiclient.enableStorageMaintenance(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all storage pools matching criteria"""
 +
 +        cmd = listStoragePools.listStoragePoolsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listStoragePools(cmd))
 +
 +    @classmethod
 +    def listForMigration(cls, apiclient, **kwargs):
 +        """List all storage pools for migration matching criteria"""
 +
 +        cmd = findStoragePoolsForMigration.findStoragePoolsForMigrationCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.findStoragePoolsForMigration(cmd))
 +
 +class Network:
 +    """Manage Network pools"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, accountid=None, domainid=None,
 +               networkofferingid=None, projectid=None,
 +               subdomainaccess=None, zoneid=None,
 +               gateway=None, netmask=None, vpcid=None, aclid=None):
 +        """Create Network for account"""
 +        cmd = createNetwork.createNetworkCmd()
 +        cmd.name = services["name"]
 +        cmd.displaytext = services["displaytext"]
 +
 +        if networkofferingid:
 +            cmd.networkofferingid = networkofferingid
 +        elif "networkoffering" in services:
 +            cmd.networkofferingid = services["networkoffering"]
 +
 +        if zoneid:
 +            cmd.zoneid = zoneid
 +        elif "zoneid" in services:
 +            cmd.zoneid = services["zoneid"]
 +
 +        if subdomainaccess is not None:
 +            cmd.subdomainaccess = subdomainaccess
 +
 +        if gateway:
 +            cmd.gateway = gateway
 +        elif "gateway" in services:
 +            cmd.gateway = services["gateway"]
 +        if netmask:
 +            cmd.netmask = netmask
 +        elif "netmask" in services:
 +            cmd.netmask = services["netmask"]
 +        if "startip" in services:
 +            cmd.startip = services["startip"]
 +        if "endip" in services:
 +            cmd.endip = services["endip"]
 +        if "vlan" in services:
 +            cmd.vlan = services["vlan"]
 +        if "acltype" in services:
 +            cmd.acltype = services["acltype"]
 +
 +        if accountid:
 +            cmd.account = accountid
 +        if domainid:
 +            cmd.domainid = domainid
 +        if projectid:
 +            cmd.projectid = projectid
 +        if vpcid:
 +            cmd.vpcid = vpcid
 +        if aclid:
 +            cmd.aclid = aclid
 +        return Network(apiclient.createNetwork(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Account"""
 +
 +        cmd = deleteNetwork.deleteNetworkCmd()
 +        cmd.id = self.id
 +        apiclient.deleteNetwork(cmd)
 +
 +    def update(self, apiclient, **kwargs):
 +        """Updates network with parameters passed"""
 +
 +        cmd = updateNetwork.updateNetworkCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.updateNetwork(cmd))
 +
 +    def restart(self, apiclient, cleanup=None):
 +        """Restarts the network"""
 +
 +        cmd = restartNetwork.restartNetworkCmd()
 +        cmd.id = self.id
 +        if cleanup:
 +            cmd.cleanup = cleanup
 +        return(apiclient.restartNetwork(cmd))
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Networks matching criteria"""
 +
 +        cmd = listNetworks.listNetworksCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listNetworks(cmd))
 +
 +
 +class NetworkACL:
 +    """Manage Network ACL lifecycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, networkid=None, protocol=None,
 +               number=None, aclid=None, action='Allow', traffictype=None, cidrlist=[]):
 +        """Create network ACL rules(Ingress/Egress)"""
 +
 +        cmd = createNetworkACL.createNetworkACLCmd()
 +        if "networkid" in services:
 +            cmd.networkid = services["networkid"]
 +        elif networkid:
 +            cmd.networkid = networkid
 +
 +        if "protocol" in services:
 +            cmd.protocol = services["protocol"]
 +            if services["protocol"] == 'ICMP':
 +                cmd.icmptype = -1
 +                cmd.icmpcode = -1
 +        elif protocol:
 +            cmd.protocol = protocol
 +
 +        if "startport" in services:
 +            cmd.startport = services["startport"]
 +        if "endport" in services:
 +            cmd.endport = services["endport"]
 +
 +        if "cidrlist" in services:
 +            cmd.cidrlist = services["cidrlist"]
 +        elif cidrlist:
 +            cmd.cidrlist = cidrlist
 +
 +        if "traffictype" in services:
 +            cmd.traffictype = services["traffictype"]
 +        elif traffictype:
 +            cmd.traffictype = traffictype
 +
 +        if "action" in services:
 +            cmd.action = services["action"]
 +        elif action:
 +            cmd.action = action
 +
 +        if "number" in services:
 +            cmd.number = services["number"]
 +        elif number:
 +            cmd.number = number
 +
 +        if "aclid" in services:
 +            cmd.aclid = services["aclid"]
 +        elif aclid:
 +            cmd.aclid = aclid
 +
 +        # Defaulted to Ingress
 +        return NetworkACL(apiclient.createNetworkACL(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete network acl"""
 +
 +        cmd = deleteNetworkACL.deleteNetworkACLCmd()
 +        cmd.id = self.id
 +        return apiclient.deleteNetworkACL(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List Network ACLs"""
 +
 +        cmd = listNetworkACLs.listNetworkACLsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listNetworkACLs(cmd))
 +
 +
 +class NetworkACLList:
 +    """Manage Network ACL lists lifecycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, name=None, description=None, vpcid=None):
 +        """Create network ACL container list"""
 +
 +        cmd = createNetworkACLList.createNetworkACLListCmd()
 +        if "name" in services:
 +            cmd.name = services["name"]
 +        elif name:
 +            cmd.name = name
 +
 +        if "description" in services:
 +            cmd.description = services["description"]
 +        elif description:
 +            cmd.description = description
 +
 +        if "vpcid" in services:
 +            cmd.vpcid = services["vpcid"]
 +        elif vpcid:
 +            cmd.vpcid = vpcid
 +
 +        return NetworkACLList(apiclient.createNetworkACLList(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete network acl list"""
 +
 +        cmd = deleteNetworkACLList.deleteNetworkACLListCmd()
 +        cmd.id = self.id
 +        return apiclient.deleteNetworkACLList(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List Network ACL lists"""
 +
 +        cmd = listNetworkACLLists.listNetworkACLListsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listNetworkACLLists(cmd))
 +
 +
 +class Vpn:
 +    """Manage VPN life cycle"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, publicipid, account=None, domainid=None,
 +                        projectid=None, networkid=None, vpcid=None):
 +        """Create VPN for Public IP address"""
 +        cmd = createRemoteAccessVpn.createRemoteAccessVpnCmd()
 +        cmd.publicipid = publicipid
 +        if account:
 +            cmd.account = account
 +        if domainid:
 +            cmd.domainid = domainid
 +        if projectid:
 +            cmd.projectid = projectid
 +        if networkid:
 +            cmd.networkid = networkid
 +        if vpcid:
 +            cmd.vpcid = vpcid
 +        return Vpn(apiclient.createRemoteAccessVpn(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete remote VPN access"""
 +
 +        cmd = deleteRemoteAccessVpn.deleteRemoteAccessVpnCmd()
 +        cmd.publicipid = self.publicipid
 +        apiclient.deleteRemoteAccessVpn(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all VPN matching criteria"""
 +
 +        cmd = listRemoteAccessVpns.listRemoteAccessVpnsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listRemoteAccessVpns(cmd))
 +
 +
 +class VpnUser:
 +    """Manage VPN user"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, username, password, account=None, domainid=None,
 +               projectid=None, rand_name=True):
 +        """Create VPN user"""
 +        cmd = addVpnUser.addVpnUserCmd()
 +        cmd.username = "-".join([username,
 +                                 random_gen()]) if rand_name else username
 +        cmd.password = password
 +
 +        if account:
 +            cmd.account = account
 +        if domainid:
 +            cmd.domainid = domainid
 +        if projectid:
 +            cmd.projectid = projectid
 +        return VpnUser(apiclient.addVpnUser(cmd).__dict__)
 +
 +    def delete(self, apiclient, projectid=None):
 +        """Remove VPN user"""
 +
 +        cmd = removeVpnUser.removeVpnUserCmd()
 +        cmd.username = self.username
 +        if projectid:
 +            cmd.projectid = projectid
 +        else:
 +            cmd.account = self.account
 +            cmd.domainid = self.domainid
 +        apiclient.removeVpnUser(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all VPN Users matching criteria"""
 +
 +        cmd = listVpnUsers.listVpnUsersCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listVpnUsers(cmd))
 +
 +
 +class Zone:
 +    """Manage Zone"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services, domainid=None):
 +        """Create zone"""
 +        cmd = createZone.createZoneCmd()
 +        cmd.dns1 = services["dns1"]
 +        cmd.internaldns1 = services["internaldns1"]
 +        cmd.name = services["name"]
 +        cmd.networktype = services["networktype"]
 +
 +        if "dns2" in services:
 +            cmd.dns2 = services["dns2"]
 +        if "internaldns2" in services:
 +            cmd.internaldns2 = services["internaldns2"]
 +        if domainid:
 +            cmd.domainid = domainid
 +        if "securitygroupenabled" in services:
 +            cmd.securitygroupenabled = services["securitygroupenabled"]
 +
 +        return Zone(apiclient.createZone(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Zone"""
 +
 +        cmd = deleteZone.deleteZoneCmd()
 +        cmd.id = self.id
 +        apiclient.deleteZone(cmd)
 +
 +    def update(self, apiclient, **kwargs):
 +        """Update the zone"""
 +
 +        cmd = updateZone.updateZoneCmd()
 +        cmd.id = self.id
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return apiclient.updateZone(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """List all Zones matching criteria"""
 +
 +        cmd = listZones.listZonesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listZones(cmd))
 +
 +
 +class Pod:
 +    """Manage Pod"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services):
 +        """Create Pod"""
 +        cmd = createPod.createPodCmd()
 +        cmd.gateway = services["gateway"]
 +        cmd.netmask = services["netmask"]
 +        cmd.name = services["name"]
 +        cmd.startip = services["startip"]
 +        cmd.endip = services["endip"]
 +        cmd.zoneid = services["zoneid"]
 +
 +        return Pod(apiclient.createPod(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Pod"""
 +
 +        cmd = deletePod.deletePodCmd()
 +        cmd.id = self.id
 +        apiclient.deletePod(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        "Returns a default pod for specified zone"
 +
 +        cmd = listPods.listPodsCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return apiclient.listPods(cmd)
 +
 +
 +class PublicIpRange:
 +    """Manage VlanIpRange"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services):
 +        """Create VlanIpRange"""
 +
 +        cmd = createVlanIpRange.createVlanIpRangeCmd()
 +        cmd.gateway = services["gateway"]
 +        cmd.netmask = services["netmask"]
 +        cmd.forvirtualnetwork = services["forvirtualnetwork"]
 +        cmd.startip = services["startip"]
 +        cmd.endip = services["endip"]
 +        cmd.zoneid = services["zoneid"]
 +        cmd.podid = services["podid"]
 +        cmd.vlan = services["vlan"]
 +
 +        return PublicIpRange(apiclient.createVlanIpRange(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete VlanIpRange"""
 +
 +        cmd = deleteVlanIpRange.deleteVlanIpRangeCmd()
 +        cmd.id = self.vlan.id
 +        apiclient.deleteVlanIpRange(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists all VLAN IP ranges."""
 +
 +        cmd = listVlanIpRanges.listVlanIpRangesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listVlanIpRanges(cmd))
 +
 +    @classmethod
 +    def dedicate(cls, apiclient, id, account=None, domainid=None, projectid=None):
 +        """Dedicate VLAN IP range"""
 +
 +        cmd = dedicatePublicIpRange.dedicatePublicIpRangeCmd()
 +        cmd.id = id
 +        cmd.account = account
 +        cmd.domainid = domainid
 +        cmd.projectid = projectid
 +        return PublicIpRange(apiclient.dedicatePublicIpRange(cmd).__dict__)
 +
 +    def release(self, apiclient):
 +        """Release VLAN IP range"""
 +
 +        cmd = releasePublicIpRange.releasePublicIpRangeCmd()
 +        cmd.id = self.vlan.id
 +        return apiclient.releasePublicIpRange(cmd)
 +
 +
 +class PortablePublicIpRange:
 +    """Manage portable public Ip Range"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, services):
 +        """Create portable public Ip Range"""
 +
 +        cmd = createPortableIpRange.createPortableIpRangeCmd()
 +        cmd.gateway = services["gateway"]
 +        cmd.netmask = services["netmask"]
 +        cmd.startip = services["startip"]
 +        cmd.endip = services["endip"]
 +        cmd.regionid = services["regionid"]
 +
 +        if "vlan" in services:
 +            cmd.vlan = services["vlan"]
 +
 +        return PortablePublicIpRange(apiclient.createPortableIpRange(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete portable IpRange"""
 +
 +        cmd = deletePortableIpRange.deletePortableIpRangeCmd()
 +        cmd.id = self.id
 +        apiclient.deletePortableIpRange(cmd)
 +
 +    @classmethod
 +    def list(cls, apiclient, **kwargs):
 +        """Lists all portable public IP ranges."""
 +
 +        cmd = listPortableIpRanges.listPortableIpRangesCmd()
 +        [setattr(cmd, k, v) for k, v in kwargs.items()]
 +        return(apiclient.listPortableIpRanges(cmd))
 +
 +class SecondaryStagingStore:
 +    """Manage Staging Store"""
 +
 +    def __init__(self, items):
 +        self.__dict__.update(items)
 +
 +    @classmethod
 +    def create(cls, apiclient, url, provider, services=None):
 +        """Create Staging Storage"""
 +        cmd = createSecondaryStagingStore.createSecondaryStagingStoreCmd()
 +        cmd.url = url
 +        cmd.provider = provider
 +        if services:
 +            if "zoneid" in services:
 +                cmd.zoneid = services["zoneid"]
 +            if "details" in services:
 +                cmd.details = services["details"]
 +            if "scope" in services:
 +                cmd.scope = services["scope"]
 +
 +        return SecondaryStagingStore(apiclient.createSecondaryStagingStore(cmd).__dict__)
 +
 +    def delete(self, apiclient):
 +        """Delete Staging Storage"""
 +        cmd = deleteSecondaryStagingStore.deleteSecondaryStagingStoreCmd()
 +        cmd.id = self.id
 +        ap

<TRUNCATED>