exoscale / cs

A simple, yet powerful CloudStack API client for python and the command-line.
BSD 3-Clause "New" or "Revised" License
88 stars 36 forks source link

Boilerplate code for resource validation and handling asynchronous calls #82

Closed synergiator closed 2 years ago

synergiator commented 5 years ago

I am not sure whether this project uses some generative/mapping technique to map to the CS API instead of implementing all calls?

If so, if possible, it would be really great to have some check functions, like:

...
    def zoneExists(self,zone):
        """Check if a specific zone is defined"""
        zones_list = self.cs.listZones()

        zones_list = zones_list['zone']
        zones=[]

        for z in zones_list:
            zones.append(z['name'])

        return zone in zones

Another example handling asynchronous calls:

class VirtualMachineManager():
    def __init__(self, cloudstack):
        self.cs = cloudstack

    def destroyVirtualMachine(self,**kwargs):
        result =  self.cs.destroyVirtualMachine(**kwargs)
        asj = AsyncJob(self.cs,result['jobid'])
        assert asj.isSuccessful() == True
        print("destroyed VM with ID: %s" % result['id'])
        return result['id']

    def deployVirtualMachine(self, **kwargs):
        result =  self.cs.deployVirtualMachine(**kwargs)
        asj = AsyncJob(self.cs,result['jobid'])
        assert asj.isSuccessful() == True
        print("created VM with ID: %s" % result['id'])
        return result['id']

    def expungeVirtualMachine(self, **kwargs):
        result =  self.cs.expungeVirtualMachine(**kwargs)
        asj = AsyncJob(self.cs,result['jobid'])
        assert asj.isSuccessful() == True
greut commented 5 years ago

This project contains no business logic. The easy way to build some is to work around the listApis call.

for you specific issue,

    def zone_exists(self, zone):
         assert zone
         zones = self.cs.listZones(name=zone, fetch_list=True)
         return bool(zones)

NB the behaviour differs if you were to check by ID.

synergiator commented 5 years ago

thanks for the shorter code - still I meant to say whether it is possible to dynamically map for API elements also sth like:

getId..
exists..

which is not explicitely there but maybe generic enough to be derivable as well

greut commented 5 years ago

Probably. I guess nobody had such needs or managed to turn them into code.

synergiator commented 5 years ago

@greut while you say, this project does not contain business logic, do you have knowledge of such a project, either would accept such code here?

That is, the boilerplate code for async calls could look like the following:

import sys

....

    def call_async(self, method, **kwargs):
        result = getattr(self.cs, method)(**kwargs)
        asj = AsyncJob(self.cs,result['jobid'])
        assert asj.isSuccessful() == True
        jobresult = asj.getResult()
        # concatenate output of async call at time of submission and
        # after successful execution
        return {**result, **jobresult}
greut commented 5 years ago

The Go projects do have the logic since static typing makes things harder. Some of them, like cloudmonkey do read the listApis and then build their inner logic. Although, the listApis information aren't always useful.