vatesfr / terraform-provider-xenorchestra

Xen Orchestra provider for Terraform
MIT License
152 stars 32 forks source link

Unify the pattern of retrieving XoObjects from the XO api #52

Closed ddelnano closed 4 years ago

ddelnano commented 4 years ago

There are two types of patterns I have been using to retrieve entities (Vm, Template, VIF, PIFs, etc) from the XO api.

The first is by having a struct implement the XoObject interface. This works by defining a Compare and New method.

type XoObject interface {
    Compare(obj map[string]interface{}) bool
    New(obj map[string]interface{}) XoObject
}

The former decides if a given object matches the entity we are searching for. The latter defines how a new struct is initialized from the data received from the xo.getAllXObjects rpc call. This leads to code like the following when a new struct type is added for a new entity (Vm, Template, VIF, etc).

func (p PIF) New(obj map[string]interface{}) XoObject {
    id := obj["id"].(string)
    device := obj["device"].(string)
    attached := obj["attached"].(bool)
    network := obj["$network"].(string)
    uuid := obj["uuid"].(string)
    poolId := obj["$poolId"].(string)
    host := obj["$host"].(string)
    vlan := int(obj["vlan"].(float64))
    return PIF{
        Device:   device,
        Host:     host,
        Network:  network,
        Id:       id,
        Uuid:     uuid,
        PoolId:   poolId,
        Attached: attached,
        Vlan:     vlan,
    }
}

This has the downside that it is a somewhat custom way of parsing JSON and in an ideal world could rely on Go struct tags to do this.

The second way, which I experimented with on #51, still uses the same interface but rather than casting the map[string]interface{} of the entity data to create the new struct it relies on Unmarshaling the data. The way it's currently implemented is rough at the moment but this method allows for using the Golang json struct tags to do this initialization. This feels like a more idiomatic way to accomplish this.

The acceptance criteria for this issue is to decide which method should be the future way of doing things and to convert all the existing code to use the correct method.

ddelnano commented 4 years ago

I was able to use reflection to accomplish this. The XoObject interface no longer requires a New method to hydrate a struct. Instead it will json decode based on the json struct tags.