Exemple #1
0
    def wmTestCloudConnection(self):
        sAccountID = uiCommon.getAjaxArg("sAccountID")
        sCloudID = uiCommon.getAjaxArg("sCloudID")

        c = cloud.Cloud()
        c.FromID(sCloudID)

        ca = cloud.CloudAccount()
        ca.FromID(sAccountID)

        # NOTE: the Cloud object has a *THIN* copy of the Provider (it doesn't include
        #    products or provider clouds.)
        # But, we actually need a full provider here, so go get it!

        full_provider = cloud.Provider.FromName(c.Provider.Name)
        cot = full_provider.GetObjectTypeByName(c.Provider.TestObject)
        if not cot:
            raise Exception("Unable to find object type [%s] on Provider [%s] in cloud_providers.xml" % (c.Provider.TestObject, c.Provider.Name))

        # different providers libs have different methods for building a url
        url = ""
        if c.Provider.Name.lower() == "amazon aws":
            # Amazon aws, Eucalyptus, and OpenStackAws
            from catocloud import aws
            awsi = aws.awsInterface()
            url, err = awsi.BuildURL(ca, c, cot)
            if err:
                raise Exception(err)
        else:  
            raise Exception("Testing connection to %s not yet supported." % (c.Provider.Name))

        if not url:
            raise Exception("Unable to build API URL.")
        result, err = catocommon.http_get(url, 30)
        if err:
            raise Exception(err)

        return json.dumps({"result": "success", "response": result})
Exemple #2
0
def GetCloudObjectsAsList(sAccountID, sCloudID, sObjectType):
    log("Querying the cloud for %s" % sObjectType, 4)

    from catocloud import cloud

    # first, get the cloud
    c = cloud.Cloud()
    c.FromID(sCloudID)
    if c is None:
        return None, "Unable to get Cloud for ID [" + sCloudID + "]"

    # NOTE: the Cloud object has a *THIN* copy of the Provider (it doesn't include
    #    products or provider clouds.)
    # But, we actually need a full provider here, so go get it!

    full_provider = cloud.Provider.FromName(c.Provider.Name)
    cot = full_provider.GetObjectTypeByName(sObjectType)
    if cot is not None:
        if not cot.ID:
            return None, "Cannot find definition for requested object type [" + sObjectType + "]"
    else:
        return None, "GetCloudObjectType failed for [" + sObjectType + "]"

    # ok, kick out if there are no properties for this type
    if not cot.Properties:
        return None, "No properties defined for type [" + sObjectType + "]"

    # All good, let's hit the API
    sXML = ""

    from catocloud import aws

    if c.Provider.Name.lower() == "openstack":
        """not yet implemented"""
        # ACWebMethods.openstackMethods acOS = new ACWebMethods.openstackMethods()
        # sXML = acOS.GetCloudObjectsAsXML(c.ID, cot, 0000BYREF_ARG0000sErr, null)
    else:  # Amazon aws, Eucalyptus, and OpenStackAws
        awsi = aws.awsInterface()
        sXML, err = awsi.GetCloudObjectsAsXML(sAccountID, sCloudID, cot)

    if err:
        return None, err

    if not sXML:
        return None, "GetCloudObjectsAsXML returned an empty document."


    # Got results, objectify them.

    # OK look, all this namespace nonsense is annoying.  Every AWS result I've witnessed HAS a namespace
    #  (which messes up all our xpaths)
    #  but I've yet to see a result that actually has two namespaces
    #  which is the only scenario I know of where you'd need them at all.

    # So... to eliminate all namespace madness
    # brute force... parse this text and remove anything that looks like [ xmlns="<crud>"] and it's contents.

    sXML = RemoveDefaultNamespacesFromXML(sXML)

    xDoc = catocommon.ET.fromstring(sXML)
    if xDoc is None:
        return None, "API Response XML document is invalid."

    log(sXML, 4)

    # FIRST ,we have to find which properties are the 'id' value.  That'll be the key for our dictionary.
    # an id can be a composite of several property values
    # this is just so we can kick back an error if no IsID exists.
    # we build the actual id from values near the end
    sIDColumnName = ""
    for prop in cot.Properties:
        if prop.IsID:
            sIDColumnName += prop.Name

    # no sIDColumnName means we can't continue
    if not sIDColumnName:
        return None, "ID column(s) not defined for Cloud Object Type" + cot.Name

    # for each result in the xml
    #     for each column
    xRecords = xDoc.findall(cot.XMLRecordXPath)
    if len(xRecords):
        for xRecord in xRecords:
            record_id = ""
            row = []
            for prop in cot.Properties:
                # NOW PAY ATTENTION.
                # the CloudObjectTypeProperty class has a 'Value' attribute.
                # but, we obviously can't set that property of THIS instance (prop)
                # because it's gonna get changed each time.

                # so, we create a clone of that property here, and give that copy the actual value,
                # then append the copy to 'row', not the one we're looping here.

                # cosmic?  yes... it is.
                newprop = copy.copy(prop)
                log("looking for property [%s]" % newprop.Name, 4)

                # ok look, the property may be an xml attribute, or it might be an element.
                # if there is an XPath value on the column, that means it's an element.
                # the absence of an XPath means we'll look for an attribute.
                # NOTE: the attribute we're looking for is the 'name' of this property
                # which is the DataColumn.name.
                if not newprop.XPath:
                    xa = xRecord.attrib[newprop.Name]
                    if xa is not None:
                        log(" -- found (attribute) - [%s]" % xa, 4)
                        newprop.Value = xa
                        row.append(newprop)
                else:
                    # if it's a tagset column put the tagset xml in it
                    #  for all other columns, they get a lookup
                    xeProp = xRecord.find(newprop.XPath)
                    if xeProp is not None:
                        # does this column have the extended property "ValueIsXML"?
                        bAsXML = (True if newprop.ValueIsXML else False)

                        if bAsXML:
                            newprop.Value = catocommon.ET.tostring(xeProp)
                            log(" -- found (as xml) - [%s]" % newprop.Value, 4)
                        else:
                            newprop.Value = xeProp.text
                            log(" -- found - [%s]" % newprop.Value, 4)

                    # just because it's missing from the data doesn't mean we can omit the property
                    # it just has an empty value.
                    row.append(newprop)

                if newprop.IsID:
                    if not newprop.Value:
                        return None, "A property [%s] cannot be defined as an 'ID', and have an empty value." % newprop.Name
                    else:
                        log("[%s] is part of the ID... so [%s] becomes part of the ID" % (newprop.Name, newprop.Value), 4)
                        record_id += (newprop.Value if newprop.Value else "")

                # an id is required
                if not record_id:
                    return None, "Unable to construct an 'id' from property values."

            cot.Instances[record_id] = row

        return cot.Instances, None
    else:
        return None, ""