I'm fairly new to Go and working on an application to create VMs in a some cloud provider. I'm trying to design interfaces and I'd love some reviews.

The application creates a cluster (group of VMs with some software installed). The cluster has two roles: master and worker. And in each role, you can have node groups (master can have only one node group and worker role can have N node groups). So a role provisions N groups and a group provisions M nodes, updating status objects after each step. Here's what I've come up with so far (I've removed method parameters to make it easy to read):

// Initialize is used to initialize objects during a cluster creation. Use this
// at the given level (Role, Group or Node) to initialize things like status
// objects specific to that level.
type Initializer interface {
    // Initialize inits objects in a Cluster type.
    Initialize() error

// StatusUpdater is used to update status of Group or Node at a given level.
type StatusUpdater interface {
    // UpdateStatus updates the ClusterStatus object.
    UpdateStatus() error

// Deleter deletes clusters, node groups and nodes.
type Deleter interface {
    // RunPreDelete is used to run things before deletion of resources.
    RunPreDelete() error
    // Delete deletes a Role, Group or Node interface.
    // RunPostDelete is used to run things after deletion of resources.
    RunPostDelete() error

// Upgrade upgrades clusters and node groups.
type Upgrader interface {
    // Upgradeable is used to determine if the cluster is ready for an upgrade.
    Upgradeable() bool
    // PrepareForUpgrade is used to prepare a Group for upgrade, like setting status to upgrading
    PrepareForUpgrade() bool

// UpgradeStategy defines strategies for upgrade. Default strategy is delete a node and create an
// "upgraded" node. The default strategy reduces workload capacity during upgrade. Additive strategy
// creates a new node and when it is ready, registers new node with the cluster and removes the old
// node. This gives additional workload capacity during upgrade. 
type UpgradeStrategy interface {
    // Upgrade upgrades a cluster or a group.
    Upgrade() error

// Ensurer ensures a resource is created and present.
type Ensurer interface {
    // Ensure ensures a resource.
    Ensure() error

// Provisioner provisions a Role (master or worker) in the cluster. This is the top level provisioner for
// a K8S cluster.
type Provisioner interface {
    // Role returns role name of the provisioner.
    Role() string
    // ProvisionRole provisions a K8S cluster role.
    ProvisionRole() error

// GroupProvisoner provisions a Group (master group and one or more worker groups).
type GroupProvisoner interface {
    // ProvisionGroup provisions a Group.
    ProvisionGroup() error

// NodeProvisioner provisions an individual node using the cloud provider APIs.
type NodeProvisioner interface {

// Node implements NodeProvisioner interface
type Node struct{}

// Group implements GroupProvisioner interface
type Group struct {
    NodeProvisioner NodeProvisioner

// Master implements Provisioner
type Master struct {
    Role            string
    GroupProvisoner GroupProvisoner
    Upgrader        Upgrader
    StatusUpdater   StatusUpdater

func NewMaster() Provisioner {
    // Inject dependencies and return a &Master

Does this look like a good design? Is it idiomatic Go? Any suggestions are greatly appreciated!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.