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.
Delete()
// 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
UpgradeStrategy
}
// 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 {
Initializer
// Role returns role name of the provisioner.
Role() string
// ProvisionRole provisions a K8S cluster role.
ProvisionRole() error
StatusUpdater
Deleter
}
// GroupProvisoner provisions a Group (master group and one or more worker groups).
type GroupProvisoner interface {
Initializer
// ProvisionGroup provisions a Group.
ProvisionGroup() error
StatusUpdater
Deleter
}
// NodeProvisioner provisions an individual node using the cloud provider APIs.
type NodeProvisioner interface {
Initializer
Ensurer
StatusUpdater
Deleter
}
// 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!
Aucun commentaire:
Enregistrer un commentaire