Skip to content

Instantly share code, notes, and snippets.

@smashwilson
Last active August 29, 2015 14:05
Show Gist options
  • Save smashwilson/8b3bcab602a5cc775f7c to your computer and use it in GitHub Desktop.
Save smashwilson/8b3bcab602a5cc775f7c to your computer and use it in GitHub Desktop.
// This is a proposal for an alternative approach to client interactions with Gophercloud.
import (
"time"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/rackspace"
)
// Provider adheres to a common gophercloud.Client interface.
// rackspace.Authenticate delegates to the "right" identity endpoint
client, err := rackspace.Authenticate(
gophercloud.AuthOptions{
Username: username,
ApiKey: apiKey,
},
}
// NewCompute handles the mechanics of searching the service catalog for a suitable endpoint of a compute service.
// "compute" adheres to a gophercloud.Compute interface.
//
// The provider can supply defaults here, such as a preferred version.
compute, err := client.NewCompute(gophercloud.ApiCriteria{Region: "IAD"})
// FindImage: a higher-level wrapper around a direct ListImages call that handles lookups by different criteria.
// Seems like we could use a similar idiom to service discovery here.
image, err := compute.FindImage(gophercloud.ImageCriteria{Name: "Ubuntu 12.04 LTS"})
// FindFlavor: same deal.
flavor, err := compute.FindFlavor(gophercloud.FlavorCriteria{RAM: 512})
// Submit a server creation request.
server, err := compute.CreateServer(gophercloud.NewServer{
Name: name,
ImageID: image.ID,
FlavorID: flavor.ID,
})
// Poll until it's created. 10s polling interval, 10m timeout.
compute.WaitForState(server.ID, "ACTIVE", 10 * time.Second, 10 * time.Minute)
// Delete a server by ID.
compute.DeleteServer(server.ID)
@smashwilson
Copy link
Author

I don't think this is too radical of a departure from the way it's already moving. The major differences are:

  • Abstract authentication and endpoint discovery into methods on a Provider type in that provider's child package. Under the hood rackspace.Authenticate just calls the existing auth methods and uses the identity service normally; we just hide it from clients unless they really care.
  • Call API services by their "type" rather than Rackspace-specific implementation names; Compute, not CloudServers. The gophercloud package defines interfaces and structs that define behavior that's shared among all providers. The compute type in rackspace/compute/v2 can implement that behavior with those names and extend it where it's appropriate. This would let clients enforce provider-agnostic code by only using gophercloud types, and let our tests enforce a certain degree of consistency among providers, but also let us extend them in arbitrary ways.

@smashwilson
Copy link
Author

Downside: if all providers share NewCompute() Compute from an interface, you'd have to cast to use provider- or version-specific behavior.

Maybe we also have methods on the Rackspace provider type like ComputeV2() that returns it appropriately typed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment