cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tall...@apache.org
Subject [57/60] [abbrv] Merge branch 'master' into marvin
Date Tue, 08 Apr 2014 12:26:12 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e223d67/tools/marvin/marvin/lib/common.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/lib/common.py
index f08cffb,0000000..62dab25
mode 100644,000000..100644
--- a/tools/marvin/marvin/lib/common.py
+++ b/tools/marvin/marvin/lib/common.py
@@@ -1,975 -1,0 +1,1097 @@@
 +# 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.
 +"""Common functions
 +"""
 +
 +# Import Local Modules
 +from marvin.cloudstackAPI import (listConfigurations,
 +                                  listPhysicalNetworks,
 +                                  listRegions,
 +                                  addNetworkServiceProvider,
 +                                  updateNetworkServiceProvider,
 +                                  listDomains,
 +                                  listZones,
 +                                  listPods,
 +                                  listOsTypes,
 +                                  listTemplates,
 +                                  updateResourceLimit,
 +                                  listRouters,
 +                                  listNetworks,
 +                                  listClusters,
 +                                  listSystemVms,
 +                                  listStoragePools,
 +                                  listVirtualMachines,
 +                                  listLoadBalancerRuleInstances,
 +                                  listFirewallRules,
 +                                  listVolumes,
 +                                  listIsos,
 +                                  listAccounts,
 +                                  listSnapshotPolicies,
 +                                  listDiskOfferings,
 +                                  listVlanIpRanges,
 +                                  listUsageRecords,
 +                                  listNetworkServiceProviders,
 +                                  listHosts,
 +                                  listPublicIpAddresses,
 +                                  listPortForwardingRules,
 +                                  listLoadBalancerRules,
 +                                  listSnapshots,
 +                                  listUsers,
 +                                  listEvents,
 +                                  listServiceOfferings,
 +                                  listVirtualRouterElements,
 +                                  listNetworkOfferings,
 +                                  listResourceLimits,
 +                                  listVPCOfferings)
- from marvin.lib.base import (Configurations,
-                              NetScaler,
-                              Template,
-                              Resources,
-                              PhysicalNetwork,
-                              Host)
- from marvin.lib.utils import (get_process_status,
-                               xsplit)
++
++
++
 +
 +from marvin.sshClient import SshClient
++from marvin.codes import (PASS, ISOLATED_NETWORK, VPC_NETWORK,
++                          BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE)
 +import random
- from utils import *
- from base import *
++from marvin.lib.utils import *
++from marvin.lib.base import *
 +from marvin.codes import PASS
- from marvin.lib.utils import validateList
++
 +
 +# Import System modules
 +import time
 +
 +
 +def is_config_suitable(apiclient, name, value):
 +    """
 +    Ensure if the deployment has the expected `value` for the global setting `name'
 +    @return: true if value is set, else false
 +    """
 +    configs = Configurations.list(apiclient, name=name)
 +    assert(
 +        configs is not None and isinstance(
 +            configs,
 +            list) and len(
 +            configs) > 0)
 +    return configs[0].value == value
 +
 +
 +def wait_for_cleanup(apiclient, configs=None):
 +    """Sleeps till the cleanup configs passed"""
 +
 +    # Configs list consists of the list of global configs
 +    if not isinstance(configs, list):
 +        return
 +    for config in configs:
 +        cmd = listConfigurations.listConfigurationsCmd()
 +        cmd.name = config
 +        cmd.listall = True
 +        try:
 +            config_descs = apiclient.listConfigurations(cmd)
 +        except Exception as e:
 +            raise Exception("Failed to fetch configurations: %s" % e)
 +
 +        if not isinstance(config_descs, list):
 +            raise Exception("List configs didn't returned a valid data")
 +
 +        config_desc = config_descs[0]
 +        # Sleep for the config_desc.value time
 +        time.sleep(int(config_desc.value))
 +    return
 +
 +
 +def add_netscaler(apiclient, zoneid, NSservice):
 +    """ Adds Netscaler device and enables NS provider"""
 +
 +    cmd = listPhysicalNetworks.listPhysicalNetworksCmd()
 +    cmd.zoneid = zoneid
 +    physical_networks = apiclient.listPhysicalNetworks(cmd)
 +    if isinstance(physical_networks, list):
 +        physical_network = physical_networks[0]
 +
 +    cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd()
 +    cmd.name = 'Netscaler'
 +    cmd.physicalnetworkid = physical_network.id
 +    nw_service_providers = apiclient.listNetworkServiceProviders(cmd)
 +
 +    if isinstance(nw_service_providers, list):
 +        netscaler_provider = nw_service_providers[0]
 +    else:
 +        cmd1 = addNetworkServiceProvider.addNetworkServiceProviderCmd()
 +        cmd1.name = 'Netscaler'
 +        cmd1.physicalnetworkid = physical_network.id
 +        netscaler_provider = apiclient.addNetworkServiceProvider(cmd1)
 +
 +    netscaler = NetScaler.add(
 +        apiclient,
 +        NSservice,
 +        physicalnetworkid=physical_network.id
 +    )
 +    if netscaler_provider.state != 'Enabled':
 +        cmd = updateNetworkServiceProvider.updateNetworkServiceProviderCmd()
 +        cmd.id = netscaler_provider.id
 +        cmd.state = 'Enabled'
 +        apiclient.updateNetworkServiceProvider(cmd)
 +
 +    return netscaler
 +
 +
 +def get_region(apiclient, region_id=None, region_name=None):
 +    '''
 +    @name : get_region
 +    @Desc : Returns the Region Information for a given region  id or region name
 +    @Input : region_name: Name of the Region
 +             region_id : Id of the region
 +    @Output : 1. Region  Information for the passed inputs else first Region
 +              2. FAILED In case the cmd failed
 +    '''
 +    cmd = listRegions.listRegionsCmd()
 +    if region_name is not None:
 +        cmd.name = region_name
 +    if region_id is not None:
 +        cmd.id = region_id
 +    cmd_out = apiclient.listRegions(cmd)
 +    return FAILED if validateList(cmd_out)[0] != PASS else cmd_out[0]
 +
 +
 +def get_domain(apiclient, domain_id=None, domain_name=None):
 +    '''
 +    @name : get_domain
 +    @Desc : Returns the Domain Information for a given domain id or domain name
 +    @Input : domain id : Id of the Domain
 +             domain_name : Name of the Domain
 +    @Output : 1. Domain  Information for the passed inputs else first Domain
 +              2. FAILED In case the cmd failed
 +    '''
 +    cmd = listDomains.listDomainsCmd()
 +
 +    if domain_name is not None:
 +        cmd.name = domain_name
 +    if domain_id is not None:
 +        cmd.id = domain_id
 +    cmd_out = apiclient.listDomains(cmd)
 +    if validateList(cmd_out)[0] != PASS:
 +        return FAILED
 +    return cmd_out[0]
 +
 +
 +def get_zone(apiclient, zone_name=None, zone_id=None):
 +    '''
 +    @name : get_zone
 +    @Desc :Returns the Zone Information for a given zone id or Zone Name
 +    @Input : zone_name: Name of the Zone
 +             zone_id : Id of the zone
 +    @Output : 1. Zone Information for the passed inputs else first zone
 +              2. FAILED In case the cmd failed
 +    '''
 +    cmd = listZones.listZonesCmd()
 +    if zone_name is not None:
 +        cmd.name = zone_name
 +    if zone_id is not None:
 +        cmd.id = zone_id
 +
 +    cmd_out = apiclient.listZones(cmd)
 +
 +    if validateList(cmd_out)[0] != PASS:
 +        return FAILED
 +    '''
 +    Check if input zone name and zone id is None,
 +    then return first element of List Zones command
 +    '''
 +    return cmd_out[0]
 +
 +
 +def get_pod(apiclient, zone_id=None, pod_id=None, pod_name=None):
 +    '''
 +    @name : get_pod
 +    @Desc :  Returns the Pod Information for a given zone id or Zone Name
 +    @Input : zone_id: Id of the Zone
 +             pod_name : Name of the Pod
 +             pod_id : Id of the Pod
 +    @Output : 1. Pod Information for the pod
 +              2. FAILED In case the cmd failed
 +    '''
 +    cmd = listPods.listPodsCmd()
 +
 +    if pod_name is not None:
 +        cmd.name = pod_name
 +    if pod_id is not None:
 +        cmd.id = pod_id
 +    if zone_id is not None:
 +        cmd.zoneid = zone_id
 +
 +    cmd_out = apiclient.listPods(cmd)
 +
 +    if validateList(cmd_out)[0] != PASS:
 +        return FAILED
 +    return cmd_out[0]
- 
- 
 +def get_template(
 +        apiclient, zone_id=None, ostype_desc=None, template_filter="featured", template_type='BUILTIN',
 +        template_id=None, template_name=None, account=None, domain_id=None, project_id=None,
 +        hypervisor=None):
 +    '''
 +    @Name : get_template
 +    @Desc : Retrieves the template Information based upon inputs provided
 +            Template is retrieved based upon either of the inputs matched
 +            condition
 +    @Input : returns a template"
 +    @Output : FAILED in case of any failure
 +              template Information matching the inputs
 +    '''
 +    cmd = listTemplates.listTemplatesCmd()
 +    cmd.templatefilter = template_filter
 +    if domain_id is not None:
 +        cmd.domainid = domain_id
 +    if zone_id is not None:
 +        cmd.zoneid = zone_id
 +    if template_id is not None:
 +        cmd.id = template_id
 +    if template_name is not None:
 +        cmd.name = template_name
 +    if hypervisor is not None:
 +        cmd.hypervisor = hypervisor
 +    if project_id is not None:
 +        cmd.projectid = project_id
 +    if account is not None:
 +        cmd.account = account
 +
 +    '''
 +    Get the Templates pertaining to the inputs provided
 +    '''
 +    list_templatesout = apiclient.listTemplates(cmd)
 +    if validateList(list_templatesout)[0] != PASS:
 +        return FAILED
 +
 +    for template in list_templatesout:
 +        if template.isready and template.templatetype == template_type:
 +            return template
 +    '''
 +    Return default first template, if no template matched
 +    '''
 +    return list_templatesout[0]
 +
 +
 +def download_systemplates_sec_storage(server, services):
 +    """Download System templates on sec storage"""
 +
 +    try:
 +        # Login to management server
 +        ssh = SshClient(
 +            server["ipaddress"],
 +            server["port"],
 +            server["username"],
 +            server["password"]
 +        )
 +    except Exception:
 +        raise Exception("SSH access failed for server with IP address: %s" %
 +                        server["ipaddess"])
 +    # Mount Secondary Storage on Management Server
 +    cmds = [
 +        "mkdir -p %s" % services["mnt_dir"],
 +        "mount -t nfs %s:/%s %s" % (
 +            services["sec_storage"],
 +            services["path"],
 +            services["mnt_dir"]
 +        ),
 +        "%s -m %s -u %s -h %s -F" % (
 +            services["command"],
 +            services["mnt_dir"],
 +            services["download_url"],
 +            services["hypervisor"]
 +        )
 +    ]
 +    for c in cmds:
 +        result = ssh.execute(c)
 +
 +    res = str(result)
 +
 +    # Unmount the Secondary storage
 +    ssh.execute("umount %s" % (services["mnt_dir"]))
 +
 +    if res.count("Successfully installed system VM template") == 1:
 +        return
 +    else:
 +        raise Exception("Failed to download System Templates on Sec Storage")
 +    return
 +
 +
 +def wait_for_ssvms(apiclient, zoneid, podid, interval=60):
 +    """After setup wait for SSVMs to come Up"""
 +
 +    time.sleep(interval)
 +    timeout = 40
 +    while True:
 +        list_ssvm_response = list_ssvms(
 +            apiclient,
 +            systemvmtype='secondarystoragevm',
 +            zoneid=zoneid,
 +            podid=podid
 +        )
 +        ssvm = list_ssvm_response[0]
 +        if ssvm.state != 'Running':
 +            # Sleep to ensure SSVMs are Up and Running
 +            time.sleep(interval)
 +            timeout = timeout - 1
 +        elif ssvm.state == 'Running':
 +            break
 +        elif timeout == 0:
 +            raise Exception("SSVM failed to come up")
 +            break
 +
 +    timeout = 40
 +    while True:
 +        list_ssvm_response = list_ssvms(
 +            apiclient,
 +            systemvmtype='consoleproxy',
 +            zoneid=zoneid,
 +            podid=podid
 +        )
 +        cpvm = list_ssvm_response[0]
 +        if cpvm.state != 'Running':
 +            # Sleep to ensure SSVMs are Up and Running
 +            time.sleep(interval)
 +            timeout = timeout - 1
 +        elif cpvm.state == 'Running':
 +            break
 +        elif timeout == 0:
 +            raise Exception("CPVM failed to come up")
 +            break
 +    return
 +
 +
 +def get_builtin_template_info(apiclient, zoneid):
 +    """Returns hypervisor specific infor for templates"""
 +
 +    list_template_response = Template.list(
 +        apiclient,
 +        templatefilter='featured',
 +        zoneid=zoneid,
 +    )
 +
 +    for b_template in list_template_response:
 +        if b_template.templatetype == 'BUILTIN':
 +            break
 +
 +    extract_response = Template.extract(apiclient,
 +                                        b_template.id,
 +                                        'HTTP_DOWNLOAD',
 +                                        zoneid)
 +
 +    return extract_response.url, b_template.hypervisor, b_template.format
 +
 +
 +def download_builtin_templates(apiclient, zoneid, hypervisor, host,
 +                               linklocalip, interval=60):
 +    """After setup wait till builtin templates are downloaded"""
 +
 +    # Change IPTABLES Rules
 +    get_process_status(
 +        host["ipaddress"],
 +        host["port"],
 +        host["username"],
 +        host["password"],
 +        linklocalip,
 +        "iptables -P INPUT ACCEPT"
 +    )
 +    time.sleep(interval)
 +    # Find the BUILTIN Templates for given Zone, Hypervisor
 +    list_template_response = list_templates(
 +        apiclient,
 +        hypervisor=hypervisor,
 +        zoneid=zoneid,
 +        templatefilter='self'
 +    )
 +
 +    if not isinstance(list_template_response, list):
 +        raise Exception("Failed to download BUILTIN templates")
 +
 +    # Ensure all BUILTIN templates are downloaded
 +    templateid = None
 +    for template in list_template_response:
 +        if template.templatetype == "BUILTIN":
 +            templateid = template.id
 +
 +    # Sleep to ensure that template is in downloading state after adding
 +    # Sec storage
 +    time.sleep(interval)
 +    while True:
 +        template_response = list_templates(
 +            apiclient,
 +            id=templateid,
 +            zoneid=zoneid,
 +            templatefilter='self'
 +        )
 +        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("ErrorInDownload")
 +
 +    return
 +
 +
 +def update_resource_limit(apiclient, resourcetype, account=None,
 +                          domainid=None, max=None, projectid=None):
 +    """Updates the resource limit to 'max' for given account"""
 +
 +    cmd = updateResourceLimit.updateResourceLimitCmd()
 +    cmd.resourcetype = resourcetype
 +    if account:
 +        cmd.account = account
 +    if domainid:
 +        cmd.domainid = domainid
 +    if max:
 +        cmd.max = max
 +    if projectid:
 +        cmd.projectid = projectid
 +    apiclient.updateResourceLimit(cmd)
 +    return
 +
 +
 +def list_os_types(apiclient, **kwargs):
 +    """List all os types matching criteria"""
 +
 +    cmd = listOsTypes.listOsTypesCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listOsTypes(cmd))
 +
 +
 +def list_routers(apiclient, **kwargs):
 +    """List all Routers matching criteria"""
 +
 +    cmd = listRouters.listRoutersCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listRouters(cmd))
 +
 +
 +def list_zones(apiclient, **kwargs):
 +    """List all Zones matching criteria"""
 +
 +    cmd = listZones.listZonesCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listZones(cmd))
 +
 +
 +def list_networks(apiclient, **kwargs):
 +    """List all Networks matching criteria"""
 +
 +    cmd = listNetworks.listNetworksCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listNetworks(cmd))
 +
 +
 +def list_clusters(apiclient, **kwargs):
 +    """List all Clusters matching criteria"""
 +
 +    cmd = listClusters.listClustersCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listClusters(cmd))
 +
 +
 +def list_ssvms(apiclient, **kwargs):
 +    """List all SSVMs matching criteria"""
 +
 +    cmd = listSystemVms.listSystemVmsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listSystemVms(cmd))
 +
 +
 +def list_storage_pools(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))
 +
 +
 +def list_virtual_machines(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 list_hosts(apiclient, **kwargs):
 +    """List all Hosts matching criteria"""
 +
 +    cmd = listHosts.listHostsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listHosts(cmd))
 +
 +
 +def list_configurations(apiclient, **kwargs):
 +    """List configuration with specified name"""
 +
 +    cmd = listConfigurations.listConfigurationsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listConfigurations(cmd))
 +
 +
 +def list_publicIP(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))
 +
 +
 +def list_nat_rules(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))
 +
 +
 +def list_lb_rules(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))
 +
 +
 +def list_lb_instances(apiclient, **kwargs):
 +    """List all Load balancing instances matching criteria"""
 +
 +    cmd = listLoadBalancerRuleInstances.listLoadBalancerRuleInstancesCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listLoadBalancerRuleInstances(cmd))
 +
 +
 +def list_firewall_rules(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))
 +
 +
 +def list_volumes(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 list_isos(apiclient, **kwargs):
 +    """Lists all available ISO files."""
 +
 +    cmd = listIsos.listIsosCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listIsos(cmd))
 +
 +
 +def list_snapshots(apiclient, **kwargs):
 +    """List all snapshots matching criteria"""
 +
 +    cmd = listSnapshots.listSnapshotsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listSnapshots(cmd))
 +
 +
 +def list_templates(apiclient, **kwargs):
 +    """List all templates matching criteria"""
 +
 +    cmd = listTemplates.listTemplatesCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listTemplates(cmd))
 +
 +
 +def list_domains(apiclient, **kwargs):
 +    """Lists domains"""
 +
 +    cmd = listDomains.listDomainsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listDomains(cmd))
 +
 +
 +def list_accounts(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 list_users(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))
 +
 +
 +def list_snapshot_policy(apiclient, **kwargs):
 +    """Lists snapshot policies."""
 +
 +    cmd = listSnapshotPolicies.listSnapshotPoliciesCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listSnapshotPolicies(cmd))
 +
 +
 +def list_events(apiclient, **kwargs):
 +    """Lists events"""
 +
 +    cmd = listEvents.listEventsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listEvents(cmd))
 +
 +
 +def list_disk_offering(apiclient, **kwargs):
 +    """Lists all available disk offerings."""
 +
 +    cmd = listDiskOfferings.listDiskOfferingsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listDiskOfferings(cmd))
 +
 +
 +def list_service_offering(apiclient, **kwargs):
 +    """Lists all available service offerings."""
 +
 +    cmd = listServiceOfferings.listServiceOfferingsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listServiceOfferings(cmd))
 +
 +
 +def list_vlan_ipranges(apiclient, **kwargs):
 +    """Lists all VLAN IP ranges."""
 +
 +    cmd = listVlanIpRanges.listVlanIpRangesCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listVlanIpRanges(cmd))
 +
 +
 +def list_usage_records(apiclient, **kwargs):
 +    """Lists usage records for accounts"""
 +
 +    cmd = listUsageRecords.listUsageRecordsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listUsageRecords(cmd))
 +
 +
 +def list_nw_service_prividers(apiclient, **kwargs):
 +    """Lists Network service providers"""
 +
 +    cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listNetworkServiceProviders(cmd))
 +
 +
 +def list_virtual_router_elements(apiclient, **kwargs):
 +    """Lists Virtual Router elements"""
 +
 +    cmd = listVirtualRouterElements.listVirtualRouterElementsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listVirtualRouterElements(cmd))
 +
 +
 +def list_network_offerings(apiclient, **kwargs):
 +    """Lists network offerings"""
 +
 +    cmd = listNetworkOfferings.listNetworkOfferingsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listNetworkOfferings(cmd))
 +
 +
 +def list_resource_limits(apiclient, **kwargs):
 +    """Lists resource limits"""
 +
 +    cmd = listResourceLimits.listResourceLimitsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listResourceLimits(cmd))
 +
 +
 +def list_vpc_offerings(apiclient, **kwargs):
 +    """ Lists VPC offerings """
 +
 +    cmd = listVPCOfferings.listVPCOfferingsCmd()
 +    [setattr(cmd, k, v) for k, v in kwargs.items()]
 +    return(apiclient.listVPCOfferings(cmd))
 +
 +
 +def update_resource_count(apiclient, domainid, accountid=None,
 +                          projectid=None, rtype=None):
 +    """updates the resource count
 +        0     - VM
 +        1     - Public IP
 +        2     - Volume
 +        3     - Snapshot
 +        4     - Template
 +        5     - Projects
 +        6     - Network
 +        7     - VPC
 +        8     - CPUs
 +        9     - RAM
 +        10    - Primary (shared) storage (Volumes)
 +        11    - Secondary storage (Snapshots, Templates & ISOs)
 +    """
 +
 +    Resources.updateCount(apiclient,
 +                          domainid=domainid,
 +                          account=accountid if accountid else None,
 +                          projectid=projectid if projectid else None,
 +                          resourcetype=rtype if rtype else None
 +                          )
 +    return
 +
- 
- def find_suitable_host(apiclient, vm):
++def findSuitableHostForMigration(apiclient, vmid):
 +    """Returns a suitable host for VM migration"""
++    suitableHost = None
++    try:
++        hosts = Host.listForMigration(apiclient, virtualmachineid=vmid,
++                )
++    except Exception as e:
++        raise Exception("Exception while getting hosts list suitable for migration: %s" % e)
 +
-     hosts = Host.list(apiclient,
-                       virtualmachineid=vm.id,
-                       listall=True)
++    suitablehosts = []
++    if isinstance(hosts, list) and len(hosts) > 0:
++        suitablehosts = [host for host in hosts if (str(host.resourcestate).lower() == "enabled"\
++                and str(host.state).lower() == "up")]
++        if len(suitablehosts)>0:
++            suitableHost = suitablehosts[0]
 +
-     if isinstance(hosts, list):
-         assert len(hosts) > 0, "List host should return valid response"
-     else:
-         raise Exception("Exception: List host should return valid response")
-     return hosts[0]
++    return suitableHost
 +
 +
 +def get_resource_type(resource_id):
 +    """Returns resource type"""
 +
 +    lookup = {0: "VM",
 +              1: "Public IP",
 +              2: "Volume",
 +              3: "Snapshot",
 +              4: "Template",
 +              5: "Projects",
 +              6: "Network",
 +              7: "VPC",
 +              8: "CPUs",
 +              9: "RAM",
 +              10: "Primary (shared) storage (Volumes)",
 +              11: "Secondary storage (Snapshots, Templates & ISOs)"
 +              }
 +
 +    return lookup[resource_id]
 +
 +
 +def get_portable_ip_range_services(config):
 +    """ Reads config values related to portable ip and fills up
 +    services accordingly"""
 +
 +    services = {}
 +    attributeError = False
 +
 +    if config.portableIpRange.startip:
 +        services["startip"] = config.portableIpRange.startip
 +    else:
 +        attributeError = True
 +
 +    if config.portableIpRange.endip:
 +        services["endip"] = config.portableIpRange.endip
 +    else:
 +        attributeError = True
 +
 +    if config.portableIpRange.netmask:
 +        services["netmask"] = config.portableIpRange.netmask
 +    else:
 +        attributeError = True
 +
 +    if config.portableIpRange.gateway:
 +        services["gateway"] = config.portableIpRange.gateway
 +    else:
 +        attributeError = True
 +
 +    if config.portableIpRange.vlan:
 +        services["vlan"] = config.portableIpRange.vlan
 +
 +    if attributeError:
 +        services = None
 +
 +    return services
 +
 +
 +def get_free_vlan(apiclient, zoneid):
 +    """
 +    Find an unallocated VLAN outside the range allocated to the physical network.
 +
 +    @note: This does not guarantee that the VLAN is available for use in
 +    the deployment's network gear
 +    @return: physical_network, shared_vlan_tag
 +    """
 +    list_physical_networks_response = PhysicalNetwork.list(
 +        apiclient,
 +        zoneid=zoneid
 +    )
 +    assert isinstance(list_physical_networks_response, list)
 +    assert len(
 +        list_physical_networks_response) > 0, "No physical networks found in zone %s" % zoneid
 +
 +    physical_network = list_physical_networks_response[0]
 +
 +    networks = list_networks(apiclient, zoneid=zoneid, type='Shared')
 +    usedVlanIds = []
 +
 +    if isinstance(networks, list) and len(networks) > 0:
 +        usedVlanIds = [int(nw.vlan)
 +                       for nw in networks if nw.vlan != "untagged"]
 +
 +    if hasattr(physical_network, "vlan") is False:
 +        while True:
 +            shared_ntwk_vlan = random.randrange(1, 4095)
 +            if shared_ntwk_vlan in usedVlanIds:
 +                continue
 +            else:
 +                break
 +    else:
 +        vlans = xsplit(physical_network.vlan, ['-', ','])
 +
 +        assert len(vlans) > 0
 +        assert int(vlans[0]) < int(
 +            vlans[-1]), "VLAN range  %s was improperly split" % physical_network.vlan
 +
 +        # Assuming random function will give different integer each time
 +        retriesCount = 20
 +
 +        shared_ntwk_vlan = None
 +
 +        while True:
 +
 +            if retriesCount == 0:
 +                break
 +
 +            free_vlan = int(vlans[-1]) + random.randrange(1, 20)
 +
 +            if free_vlan > 4095:
 +                free_vlan = int(vlans[0]) - random.randrange(1, 20)
 +            if free_vlan < 0 or (free_vlan in usedVlanIds):
 +                retriesCount -= 1
 +                continue
 +            else:
 +                shared_ntwk_vlan = free_vlan
 +                break
 +
 +    return physical_network, shared_ntwk_vlan
 +
 +
 +def setNonContiguousVlanIds(apiclient, zoneid):
 +    """
 +    Form the non contiguous ranges based on currently assigned range in physical network
 +    """
 +
 +    NonContigVlanIdsAcquired = False
 +
 +    list_physical_networks_response = PhysicalNetwork.list(
 +        apiclient,
 +        zoneid=zoneid
 +    )
 +    assert isinstance(list_physical_networks_response, list)
 +    assert len(
 +        list_physical_networks_response) > 0, "No physical networks found in zone %s" % zoneid
 +
 +    for physical_network in list_physical_networks_response:
 +
 +        vlans = xsplit(physical_network.vlan, ['-', ','])
 +
 +        assert len(vlans) > 0
 +        assert int(vlans[0]) < int(
 +            vlans[-1]), "VLAN range  %s was improperly split" % physical_network.vlan
 +
 +        # Keep some gap between existing vlan and the new vlans which we are going to add
 +        # So that they are non contiguous
 +
 +        non_contig_end_vlan_id = int(vlans[-1]) + 6
 +        non_contig_start_vlan_id = int(vlans[0]) - 6
 +
 +        # Form ranges which are consecutive to existing ranges but not immediately contiguous
 +        # There should be gap in between existing range and new non contiguous
 +        # ranage
 +
 +        # If you can't add range after existing range, because it's crossing 4095, then
 +        # select VLAN ids before the existing range such that they are greater than 0, and
 +        # then add this non contiguoud range
 +        vlan = {"partial_range": ["", ""], "full_range": ""}
 +
 +        if non_contig_end_vlan_id < 4095:
 +            vlan["partial_range"][0] = str(
 +                non_contig_end_vlan_id - 4) + '-' + str(non_contig_end_vlan_id - 3)
 +            vlan["partial_range"][1] = str(
 +                non_contig_end_vlan_id - 1) + '-' + str(non_contig_end_vlan_id)
 +            vlan["full_range"] = str(
 +                non_contig_end_vlan_id - 4) + '-' + str(non_contig_end_vlan_id)
 +            NonContigVlanIdsAcquired = True
 +
 +        elif non_contig_start_vlan_id > 0:
 +            vlan["partial_range"][0] = str(
 +                non_contig_start_vlan_id) + '-' + str(non_contig_start_vlan_id + 1)
 +            vlan["partial_range"][1] = str(
 +                non_contig_start_vlan_id + 3) + '-' + str(non_contig_start_vlan_id + 4)
 +            vlan["full_range"] = str(
 +                non_contig_start_vlan_id) + '-' + str(non_contig_start_vlan_id + 4)
 +            NonContigVlanIdsAcquired = True
 +
 +        else:
 +            NonContigVlanIdsAcquired = False
 +
 +        # If failed to get relevant vlan ids, continue to next physical network
 +        # else break from loop as we have hot the non contiguous vlan ids for
 +        # the test purpose
 +
 +        if not NonContigVlanIdsAcquired:
 +            continue
 +        else:
 +            break
 +
 +    # If even through looping from all existing physical networks, failed to get relevant non
 +    # contiguous vlan ids, then fail the test case
 +
 +    if not NonContigVlanIdsAcquired:
 +        return None, None
 +
 +    return physical_network, vlan
++
++def is_public_ip_in_correct_state(apiclient, ipaddressid, state):
++    """ Check if the given IP is in the correct state (given)
++    and return True/False accordingly"""
++    retriesCount = 10
++    while True:
++        portableips = PublicIPAddress.list(apiclient, id=ipaddressid)
++        assert validateList(portableips)[0] == PASS, "IPs list validation failed"
++        if str(portableips[0].state).lower() == state:
++            break
++        elif retriesCount == 0:
++           return False
++        else:
++            retriesCount -= 1
++            time.sleep(60)
++            continue
++    return True
++
++def setSharedNetworkParams(networkServices, range=20):
++    """Fill up the services dictionary for shared network using random subnet"""
++
++    # @range: range decides the endip. Pass the range as "x" if you want the difference between the startip
++    # and endip as "x"
++    # Set the subnet number of shared networks randomly prior to execution
++    # of each test case to avoid overlapping of ip addresses
++    shared_network_subnet_number = random.randrange(1,254)
++
++    networkServices["gateway"] = "172.16."+str(shared_network_subnet_number)+".1"
++    networkServices["startip"] = "172.16."+str(shared_network_subnet_number)+".2"
++    networkServices["endip"] = "172.16."+str(shared_network_subnet_number)+"."+str(range+1)
++    networkServices["netmask"] = "255.255.255.0"
++    return networkServices
++
++def createEnabledNetworkOffering(apiclient, networkServices):
++    """Create and enable network offering according to the type
++
++       @output: List, containing [ Result,Network Offering,Reason ]
++                 Ist Argument('Result') : FAIL : If exception or assertion error occurs
++                                          PASS : If network offering
++                                          is created and enabled successfully
++                 IInd Argument(Net Off) : Enabled network offering
++                                                In case of exception or
++                                                assertion error, it will be None
++                 IIIrd Argument(Reason) :  Reason for failure,
++                                              default to None
++    """
++    try:
++        resultSet = [FAIL, None, None]
++        # Create network offering
++        network_offering = NetworkOffering.create(apiclient, networkServices, conservemode=False)
++
++        # Update network offering state from disabled to enabled.
++        NetworkOffering.update(network_offering, apiclient, id=network_offering.id,
++                               state="enabled")
++    except Exception as e:
++        resultSet[2] = e
++        return resultSet
++    return [PASS, network_offering, None]
++
++def shouldTestBeSkipped(networkType, zoneType):
++    """Decide which test to skip, according to type of network and zone type"""
++
++    # If network type is isolated or vpc and zone type is basic, then test should be skipped
++    skipIt = False
++    if ((networkType.lower() == str(ISOLATED_NETWORK).lower() or networkType.lower() == str(VPC_NETWORK).lower())
++            and (zoneType.lower() == BASIC_ZONE)):
++        skipIt = True
++    return skipIt
++
++def verifyNetworkState(apiclient, networkid, state):
++    """List networks and check if the network state matches the given state"""
++    try:
++        networks = Network.list(apiclient, id=networkid)
++    except Exception as e:
++        raise Exception("Failed while fetching network list with error: %s" % e)
++    assert validateList(networks)[0] == PASS, "Networks list validation failed, list is %s" % networks
++    assert str(networks[0].state).lower() == state, "network state should be %s, it is %s" % (state, networks[0].state)
++    return
++
++def verifyComputeOfferingCreation(apiclient, computeofferingid):
++    """List Compute offerings by ID and verify that the offering exists"""
++
++    cmd = listServiceOfferings.listServiceOfferingsCmd()
++    cmd.id = computeofferingid
++    serviceOfferings = None
++    try:
++        serviceOfferings = apiclient.listServiceOfferings(cmd)
++    except Exception:
++       return FAIL
++    if not (isinstance(serviceOfferings, list) and len(serviceOfferings) > 0):
++       return FAIL
++    return PASS
++
++def createNetworkRulesForVM(apiclient, virtualmachine, ruletype,
++                            account, networkruledata):
++    """Acquire IP, create Firewall and NAT/StaticNAT rule
++        (associating it with given vm) for that IP"""
++
++    try:
++        public_ip = PublicIPAddress.create(
++                apiclient,accountid=account.name,
++                zoneid=virtualmachine.zoneid,domainid=account.domainid,
++                networkid=virtualmachine.nic[0].networkid)
++
++        FireWallRule.create(
++            apiclient,ipaddressid=public_ip.ipaddress.id,
++            protocol='TCP', cidrlist=[networkruledata["fwrule"]["cidr"]],
++            startport=networkruledata["fwrule"]["startport"],
++            endport=networkruledata["fwrule"]["endport"]
++            )
++
++        if ruletype == NAT_RULE:
++            # Create NAT rule
++            NATRule.create(apiclient, virtualmachine,
++                                 networkruledata["natrule"],ipaddressid=public_ip.ipaddress.id,
++                                 networkid=virtualmachine.nic[0].networkid)
++        elif ruletype == STATIC_NAT_RULE:
++            # Enable Static NAT for VM
++            StaticNATRule.enable(apiclient,public_ip.ipaddress.id,
++                                     virtualmachine.id, networkid=virtualmachine.nic[0].networkid)
++    except Exception as e:
++        [FAIL, e]
++    return [PASS, public_ip]

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0e223d67/tools/marvin/marvin/lib/utils.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/lib/utils.py
index 7617f90,0000000..cb5dcfb
mode 100644,000000..100644
--- a/tools/marvin/marvin/lib/utils.py
+++ b/tools/marvin/marvin/lib/utils.py
@@@ -1,473 -1,0 +1,498 @@@
 +# 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.
 +"""Utilities functions
 +"""
 +
 +import marvin
 +import os
 +import time
 +import logging
 +import string
 +import random
 +import imaplib
 +import email
 +import socket
 +import urlparse
 +import datetime
++from marvin.cloudstackAPI import cloudstackAPIClient, listHosts, listRouters
 +from platform import system
- from marvin.cloudstackAPI import cloudstackAPIClient, listHosts
 +from marvin.cloudstackException import GetDetailExceptionInfo
 +from marvin.sshClient import SshClient
 +from marvin.codes import (
 +                          SUCCESS,
 +                          FAIL,
 +                          PASS,
 +                          MATCH_NOT_FOUND,
 +                          INVALID_INPUT,
 +                          EMPTY_LIST,
 +                          FAILED)
 +
 +def restart_mgmt_server(server):
 +    """Restarts the management server"""
 +
 +    try:
 +        # Get the SSH client
 +        ssh = is_server_ssh_ready(
 +            server["ipaddress"],
 +            server["port"],
 +            server["username"],
 +            server["password"],
 +        )
 +        result = ssh.execute("/etc/init.d/cloud-management restart")
 +        res = str(result)
 +        # Server Stop - OK
 +        # Server Start - OK
 +        if res.count("OK") != 2:
 +            raise ("ErrorInReboot!")
 +    except Exception as e:
 +        raise e
 +    return
 +
 +
 +def fetch_latest_mail(services, from_mail):
 +    """Fetch mail"""
 +
 +    # Login to mail server to verify email
 +    mail = imaplib.IMAP4_SSL(services["server"])
 +    mail.login(
 +        services["email"],
 +        services["password"]
 +    )
 +    mail.list()
 +    mail.select(services["folder"])
 +    date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y")
 +
 +    result, data = mail.uid(
 +        'search',
 +        None,
 +        '(SENTSINCE {date} HEADER FROM "{mail}")'.format(
 +            date=date,
 +            mail=from_mail
 +        )
 +    )
 +    # Return False if email is not present
 +    if data == []:
 +        return False
 +
 +    latest_email_uid = data[0].split()[-1]
 +    result, data = mail.uid('fetch', latest_email_uid, '(RFC822)')
 +    raw_email = data[0][1]
 +    email_message = email.message_from_string(raw_email)
 +    result = get_first_text_block(email_message)
 +    return result
 +
 +
 +def get_first_text_block(email_message_instance):
 +    """fetches first text block from the mail"""
 +    maintype = email_message_instance.get_content_maintype()
 +    if maintype == 'multipart':
 +        for part in email_message_instance.get_payload():
 +            if part.get_content_maintype() == 'text':
 +                return part.get_payload()
 +    elif maintype == 'text':
 +        return email_message_instance.get_payload()
 +
 +
 +def random_gen(id=None, size=6, chars=string.ascii_uppercase + string.digits):
 +    """Generate Random Strings of variable length"""
 +    randomstr = ''.join(random.choice(chars) for x in range(size))
 +    if id:
 +        return ''.join([id, '-', randomstr])
 +    return randomstr
 +
 +
 +def cleanup_resources(api_client, resources):
 +    """Delete resources"""
 +    for obj in resources:
 +        obj.delete(api_client)
 +
 +
 +def is_server_ssh_ready(ipaddress, port, username, password, retries=20, retryinterv=30, timeout=10.0, keyPairFileLocation=None):
 +    '''
 +    @Name: is_server_ssh_ready
 +    @Input: timeout: tcp connection timeout flag,
 +            others information need to be added
 +    @Output:object for SshClient
 +    Name of the function is little misnomer and is not
 +              verifying anything as such mentioned
 +    '''
 +
 +    try:
 +        ssh = SshClient(
 +            host=ipaddress,
 +            port=port,
 +            user=username,
 +            passwd=password,
 +            keyPairFiles=keyPairFileLocation,
 +            retries=retries,
 +            delay=retryinterv,
 +            timeout=timeout)
 +    except Exception, e:
 +        raise Exception("SSH connection has Failed. Waited %ss. Error is %s" % (retries * retryinterv, str(e)))
 +    else:
 +        return ssh
 +
 +
 +def format_volume_to_ext3(ssh_client, device="/dev/sda"):
 +    """Format attached storage to ext3 fs"""
 +    cmds = [
 +        "echo -e 'n\np\n1\n\n\nw' | fdisk %s" % device,
 +        "mkfs.ext3 %s1" % device,
 +    ]
 +    for c in cmds:
 +        ssh_client.execute(c)
 +
 +
 +def fetch_api_client(config_file='datacenterCfg'):
 +    """Fetch the Cloudstack API Client"""
 +    config = marvin.configGenerator.get_setup_config(config_file)
 +    mgt = config.mgtSvr[0]
 +    testClientLogger = logging.getLogger("testClient")
 +    asyncTimeout = 3600
 +    return cloudstackAPIClient.CloudStackAPIClient(
 +        marvin.cloudstackConnection.cloudConnection(
 +            mgt,
 +            asyncTimeout,
 +            testClientLogger
 +        )
 +    )
 +
 +def get_host_credentials(config, hostip):
 +    """Get login information for a host `hostip` (ipv4) from marvin's `config`
 +
 +    @return the tuple username, password for the host else raise keyerror"""
 +    for zone in config.zones:
 +        for pod in zone.pods:
 +            for cluster in pod.clusters:
 +                for host in cluster.hosts:
 +                    if str(host.url).startswith('http'):
 +                        hostname = urlparse.urlsplit(str(host.url)).netloc
 +                    else:
 +                        hostname = str(host.url)
 +                    try:
 +                        if socket.getfqdn(hostip) == socket.getfqdn(hostname):
 +                            return host.username, host.password
 +                    except socket.error, e:
 +                        raise Exception("Unresolvable host %s error is %s" % (hostip, e))
 +    raise KeyError("Please provide the marvin configuration file with credentials to your hosts")
 +
 +
 +def get_process_status(hostip, port, username, password, linklocalip, process, hypervisor=None):
 +    """Double hop and returns a process status"""
 +
 +    #SSH to the machine
 +    ssh = SshClient(hostip, port, username, password)
-     if str(hypervisor).lower() == 'vmware':
++    if (str(hypervisor).lower() == 'vmware'
++		or str(hypervisor).lower() == 'hyperv'):
 +        ssh_command = "ssh -i /var/cloudstack/management/.ssh/id_rsa -ostricthostkeychecking=no "
 +    else:
 +        ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "
 +
 +    ssh_command = ssh_command +\
 +                  "-oUserKnownHostsFile=/dev/null -p 3922 %s %s" % (
 +                      linklocalip,
 +                      process)
 +
 +    # Double hop into router
 +    timeout = 5
 +    # Ensure the SSH login is successful
 +    while True:
 +        res = ssh.execute(ssh_command)
 +
 +        if res[0] != "Host key verification failed.":
 +            break
 +        elif timeout == 0:
 +            break
 +
 +        time.sleep(5)
 +        timeout = timeout - 1
 +    return res
 +
 +
 +def isAlmostEqual(first_digit, second_digit, range=0):
 +    digits_equal_within_range = False
 +
 +    try:
 +        if ((first_digit - range) < second_digit < (first_digit + range)):
 +            digits_equal_within_range = True
 +    except Exception as e:
 +        raise e
 +    return digits_equal_within_range
 +
 +
 +def xsplit(txt, seps):
 +    """
 +    Split a string in `txt` by list of delimiters in `seps`
 +    @param txt: string to split
 +    @param seps: list of separators
 +    @return: list of split units
 +    """
 +    default_sep = seps[0]
 +    for sep in seps[1:]: # we skip seps[0] because that's the default separator
 +        txt = txt.replace(sep, default_sep)
 +    return [i.strip() for i in txt.split(default_sep)]
 +
 +def get_hypervisor_type(apiclient):
 +
 +    """Return the hypervisor type of the hosts in setup"""
 +
 +    cmd = listHosts.listHostsCmd()
 +    cmd.type = 'Routing'
 +    cmd.listall = True
 +    hosts = apiclient.listHosts(cmd)
 +    hosts_list_validation_result = validateList(hosts)
 +    assert hosts_list_validation_result[0] == PASS, "host list validation failed"
 +    return hosts_list_validation_result[1].hypervisor
 +
 +def is_snapshot_on_nfs(apiclient, dbconn, config, zoneid, snapshotid):
 +    """
 +    Checks whether a snapshot with id (not UUID) `snapshotid` is present on the nfs storage
 +
 +    @param apiclient: api client connection
 +    @param @dbconn:  connection to the cloudstack db
 +    @param config: marvin configuration file
 +    @param zoneid: uuid of the zone on which the secondary nfs storage pool is mounted
 +    @param snapshotid: uuid of the snapshot
 +    @return: True if snapshot is found, False otherwise
 +    """
 +    # snapshot extension to be appended to the snapshot path obtained from db
 +    snapshot_extensions = {"vmware": ".ovf",
 +                            "kvm": "",
 +                            "xenserver": ".vhd",
 +                            "simulator":""}
 +
 +    qresultset = dbconn.execute(
 +                        "select id from snapshots where uuid = '%s';" \
 +                        % str(snapshotid)
 +                        )
 +    if len(qresultset) == 0:
 +        raise Exception(
 +            "No snapshot found in cloudstack with id %s" % snapshotid)
 +
 +
 +    snapshotid = qresultset[0][0]
 +    qresultset = dbconn.execute(
 +        "select install_path,store_id from snapshot_store_ref where snapshot_id='%s' and store_role='Image';" % snapshotid
 +    )
 +
 +    assert isinstance(qresultset, list), "Invalid db query response for snapshot %s" % snapshotid
 +
 +    if len(qresultset) == 0:
 +        #Snapshot does not exist
 +        return False
 +
 +    from base import ImageStore
 +    #pass store_id to get the exact storage pool where snapshot is stored
 +    secondaryStores = ImageStore.list(apiclient, zoneid=zoneid, id=int(qresultset[0][1]))
 +
 +    assert isinstance(secondaryStores, list), "Not a valid response for listImageStores"
 +    assert len(secondaryStores) != 0, "No image stores found in zone %s" % zoneid
 +
 +    secondaryStore = secondaryStores[0]
 +
 +    if str(secondaryStore.providername).lower() != "nfs":
 +        raise Exception(
 +            "is_snapshot_on_nfs works only against nfs secondary storage. found %s" % str(secondaryStore.providername))
 +
 +    hypervisor = get_hypervisor_type(apiclient)
 +    # append snapshot extension based on hypervisor, to the snapshot path
 +    snapshotPath = str(qresultset[0][0]) + snapshot_extensions[str(hypervisor).lower()]
 +
 +    nfsurl = secondaryStore.url
 +    from urllib2 import urlparse
 +    parse_url = urlparse.urlsplit(nfsurl, scheme='nfs')
 +    host, path = parse_url.netloc, parse_url.path
 +
 +    if not config.mgtSvr:
 +        raise Exception("Your marvin configuration does not contain mgmt server credentials")
 +    mgtSvr, user, passwd = config.mgtSvr[0].mgtSvrIp, config.mgtSvr[0].user, config.mgtSvr[0].passwd
 +
 +    try:
 +        ssh_client = SshClient(
 +            mgtSvr,
 +            22,
 +            user,
 +            passwd
 +        )
 +        cmds = [
 +                "mkdir -p %s /mnt/tmp",
 +                "mount -t %s %s%s /mnt/tmp" % (
 +                    'nfs',
 +                    host,
 +                    path,
 +                    ),
 +                "test -f %s && echo 'snapshot exists'" % (
 +                    os.path.join("/mnt/tmp", snapshotPath)
 +                    ),
 +            ]
 +
 +        for c in cmds:
 +            result = ssh_client.execute(c)
 +
 +        # Unmount the Sec Storage
 +        cmds = [
 +                "cd",
 +                "umount /mnt/tmp",
 +            ]
 +        for c in cmds:
 +            ssh_client.execute(c)
 +    except Exception as e:
 +        raise Exception("SSH failed for management server: %s - %s" %
 +                      (config.mgtSvr[0].mgtSvrIp, e))
 +    return 'snapshot exists' in result
 +
 +def validateList(inp):
 +    """
 +    @name: validateList
 +    @Description: 1. A utility function to validate
 +                 whether the input passed is a list
 +              2. The list is empty or not
 +              3. If it is list and not empty, return PASS and first element
 +              4. If not reason for FAIL
 +        @Input: Input to be validated
 +        @output: List, containing [ Result,FirstElement,Reason ]
 +                 Ist Argument('Result') : FAIL : If it is not a list
 +                                          If it is list but empty
 +                                         PASS : If it is list and not empty
 +                 IInd Argument('FirstElement'): If it is list and not empty,
 +                                           then first element
 +                                            in it, default to None
 +                 IIIrd Argument( 'Reason' ):  Reason for failure ( FAIL ),
 +                                              default to None.
 +                                              INVALID_INPUT
 +                                              EMPTY_LIST
 +    """
 +    ret = [FAIL, None, None]
 +    if inp is None:
 +        ret[2] = INVALID_INPUT
 +        return ret
 +    if not isinstance(inp, list):
 +        ret[2] = INVALID_INPUT
 +        return ret
 +    if len(inp) == 0:
 +        ret[2] = EMPTY_LIST
 +        return ret
 +    return [PASS, inp[0], None]
 +
 +def verifyElementInList(inp, toverify, responsevar=None,  pos=0):
 +    '''
 +    @name: verifyElementInList
 +    @Description:
 +    1. A utility function to validate
 +    whether the input passed is a list.
 +    The list is empty or not.
 +    If it is list and not empty, verify
 +    whether a given element is there in that list or not
 +    at a given pos
 +    @Input:
 +             I   : Input to be verified whether its a list or not
 +             II  : Element to verify whether it exists in the list 
 +             III : variable name in response object to verify 
 +                   default to None, if None, we will verify for the complete 
 +                   first element EX: state of response object object
 +             IV  : Position in the list at which the input element to verify
 +                   default to 0
 +    @output: List, containing [ Result,Reason ]
 +             Ist Argument('Result') : FAIL : If it is not a list
 +                                      If it is list but empty
 +                                      PASS : If it is list and not empty
 +                                              and matching element was found
 +             IIrd Argument( 'Reason' ): Reason for failure ( FAIL ),
 +                                        default to None.
 +                                        INVALID_INPUT
 +                                        EMPTY_LIST
 +                                        MATCH_NOT_FOUND
 +    '''
 +    if toverify is None or toverify == '' \
 +       or pos is None or pos < -1 or pos == '':
 +        return [FAIL, INVALID_INPUT]
 +    out = validateList(inp)
 +    if out[0] == FAIL:
 +        return [FAIL, out[2]]
 +    if len(inp) > pos:
 +        if responsevar is None:
 +                if inp[pos] == toverify:
 +                    return [PASS, None]
 +        else:
 +                if responsevar in inp[pos].__dict__ and getattr(inp[pos], responsevar) == toverify:
 +                    return [PASS, None]
 +                else:
 +                    return [FAIL, MATCH_NOT_FOUND]
 +    else:
 +        return [FAIL, MATCH_NOT_FOUND]
 +
- 
 +def checkVolumeSize(ssh_handle=None,
 +                    volume_name="/dev/sda",
 +                    cmd_inp="/sbin/fdisk -l | grep Disk",
 +                    size_to_verify=0):
 +    '''
 +    @Name : getDiskUsage
 +    @Desc : provides facility to verify the volume size against the size to verify
 +    @Input: 1. ssh_handle : machine against which to execute the disk size cmd
 +            2. volume_name : The name of the volume against which to verify the size
 +            3. cmd_inp : Input command used to veify the size
 +            4. size_to_verify: size against which to compare.
 +    @Output: Returns FAILED in case of an issue, else SUCCESS
 +    '''
 +    try:
 +        if ssh_handle is None or cmd_inp is None or volume_name is None:
 +            return INVALID_INPUT
 +
 +        cmd = cmd_inp
 +        '''
 +        Retrieve the cmd output
 +        '''
 +        if system().lower() != "windows":
 +            fdisk_output = ssh_handle.runCommand(cmd_inp)
 +            if fdisk_output["status"] != SUCCESS:
 +                return FAILED
 +            temp_out = fdisk_output["stdout"]
 +            for line in temp_out.split("\n"):
 +                if volume_name in line:
 +                    parts = line.split()
 +                    if str(parts[-2]) == str(size_to_verify):
 +                        return [SUCCESS,str(parts[-2])]
 +            return [FAILED,"Volume Not Found"]
 +    except Exception, e:
 +        print "\n Exception Occurred under getDiskUsage: " \
 +              "%s" %GetDetailExceptionInfo(e)
 +        return [FAILED,GetDetailExceptionInfo(e)]
++
++        
++def verifyRouterState(apiclient, routerid, allowedstates):
++    """List the router and verify that its state is in allowed states
++    @output: List, containing [Result, Reason]
++             Ist Argument ('Result'): FAIL: If router state is not
++                                                in allowed states
++                                          PASS: If router state is in
++                                                allowed states"""
++
++    try:
++        cmd = listRouters.listRoutersCmd()
++        cmd.id = routerid
++        cmd.listall = True
++        routers = apiclient.listRouters(cmd)
++    except Exception as e:
++        return [FAIL, e]
++    listvalidationresult = validateList(routers)
++    if listvalidationresult[0] == FAIL:
++        return [FAIL, listvalidationresult[2]]
++    if routers[0].redundantstate not in allowedstates:
++        return [FAIL, "Redundant state of the router should be in %s but is %s" %
++            (allowedstates, routers[0].redundantstate)]
++    return [PASS, None]
++        


Mime
View raw message