220 lines
5.9 KiB
Go
220 lines
5.9 KiB
Go
package client
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/yunify/qingcloud-sdk-go/config"
|
|
"github.com/yunify/qingcloud-sdk-go/service"
|
|
)
|
|
|
|
const (
|
|
//InstanceStatusPending pending
|
|
InstanceStatusPending = "pending"
|
|
//InstanceStatusRunning running
|
|
InstanceStatusRunning = "running"
|
|
//InstanceStatusStopped stopped
|
|
InstanceStatusStopped = "stopped"
|
|
//InstanceStatusSuspended suspended
|
|
InstanceStatusSuspended = "suspended"
|
|
//InstanceStatusTerminated terminated
|
|
InstanceStatusTerminated = "terminated"
|
|
//InstanceStatusCeased ceased
|
|
InstanceStatusCeased = "ceased"
|
|
|
|
//LoadBalancerStatusPending pending
|
|
LoadBalancerStatusPending = "pending"
|
|
//LoadBalancerStatusActive active
|
|
LoadBalancerStatusActive = "active"
|
|
//LoadBalancerStatusStopped stopped
|
|
LoadBalancerStatusStopped = "stopped"
|
|
//LoadBalancerStatusSuspended suspended
|
|
LoadBalancerStatusSuspended = "suspended"
|
|
//LoadBalancerStatusDeleted deleted
|
|
LoadBalancerStatusDeleted = "deleted"
|
|
//LoadBalancerStatusCeased ceased
|
|
LoadBalancerStatusCeased = "ceased"
|
|
|
|
//JobStatusUnknown unknown
|
|
JobStatusUnknown = "unknown"
|
|
//JobStatusSuccessful successful
|
|
JobStatusSuccessful = "successful"
|
|
//JobStatusFailed failed
|
|
JobStatusFailed = "failed"
|
|
//JobStatusPending pending
|
|
JobStatusPending = "pending"
|
|
//JobStatusWorking working
|
|
JobStatusWorking = "working"
|
|
|
|
defaultOpTimeout = 180 * time.Second
|
|
defaultWaitInterval = 10 * time.Second
|
|
)
|
|
|
|
// QingCloudClient QingCloud IaaS Advanced Client
|
|
type QingCloudClient interface {
|
|
RunInstance(arg *service.RunInstancesInput) (*service.Instance, error)
|
|
DescribeInstance(instanceID string) (*service.Instance, error)
|
|
StartInstance(instanceID string) error
|
|
StopInstance(instanceID string, force bool) error
|
|
RestartInstance(instanceID string) error
|
|
TerminateInstance(instanceID string) error
|
|
WaitInstanceStatus(instanceID string, status string) (*service.Instance, error)
|
|
}
|
|
|
|
// NewClient return a new QingCloudClient
|
|
func NewClient(config *config.Config, zone string) (QingCloudClient, error) {
|
|
qcService, err := service.Init(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
instanceService, err := qcService.Instance(zone)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
jobService, err := qcService.Job(zone)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c := &client{
|
|
InstanceService: instanceService,
|
|
JobService: jobService,
|
|
OperationTimeout: defaultOpTimeout,
|
|
WaitInterval: defaultWaitInterval,
|
|
zone: zone,
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
type client struct {
|
|
InstanceService *service.InstanceService
|
|
JobService *service.JobService
|
|
OperationTimeout time.Duration
|
|
WaitInterval time.Duration
|
|
zone string
|
|
}
|
|
|
|
// RunInstance
|
|
func (c *client) RunInstance(input *service.RunInstancesInput) (*service.Instance, error) {
|
|
|
|
output, err := c.InstanceService.RunInstances(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(output.Instances) == 0 {
|
|
return nil, errors.New("Create instance response error")
|
|
}
|
|
jobID := output.JobID
|
|
jobErr := c.waitJob(*jobID)
|
|
if jobErr != nil {
|
|
return nil, jobErr
|
|
}
|
|
instanceID := *output.Instances[0]
|
|
_, waitErr := c.WaitInstanceStatus(instanceID, InstanceStatusRunning)
|
|
if waitErr != nil {
|
|
return nil, waitErr
|
|
}
|
|
ins, waitErr := c.waitInstanceNetwork(instanceID)
|
|
if waitErr != nil {
|
|
return nil, waitErr
|
|
}
|
|
return ins, nil
|
|
}
|
|
|
|
// DescribeInstance
|
|
func (c *client) DescribeInstance(instanceID string) (*service.Instance, error) {
|
|
input := &service.DescribeInstancesInput{Instances: []*string{&instanceID}}
|
|
output, err := c.InstanceService.DescribeInstances(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(output.InstanceSet) == 0 {
|
|
return nil, fmt.Errorf("Instance with id [%s] not exist", instanceID)
|
|
}
|
|
return output.InstanceSet[0], nil
|
|
}
|
|
|
|
// StartInstance
|
|
func (c *client) StartInstance(instanceID string) error {
|
|
input := &service.StartInstancesInput{Instances: []*string{&instanceID}}
|
|
output, err := c.InstanceService.StartInstances(input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
jobID := output.JobID
|
|
waitErr := c.waitJob(*jobID)
|
|
if waitErr != nil {
|
|
return waitErr
|
|
}
|
|
_, err = c.WaitInstanceStatus(instanceID, InstanceStatusRunning)
|
|
return err
|
|
}
|
|
|
|
// StopInstance
|
|
func (c *client) StopInstance(instanceID string, force bool) error {
|
|
var forceParam int
|
|
if force {
|
|
forceParam = 1
|
|
} else {
|
|
forceParam = 0
|
|
}
|
|
input := &service.StopInstancesInput{Instances: []*string{&instanceID}, Force: &forceParam}
|
|
output, err := c.InstanceService.StopInstances(input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
jobID := output.JobID
|
|
waitErr := c.waitJob(*jobID)
|
|
if waitErr != nil {
|
|
return waitErr
|
|
}
|
|
_, err = c.WaitInstanceStatus(instanceID, InstanceStatusStopped)
|
|
return err
|
|
}
|
|
|
|
// RestartInstance
|
|
func (c *client) RestartInstance(instanceID string) error {
|
|
input := &service.RestartInstancesInput{Instances: []*string{&instanceID}}
|
|
output, err := c.InstanceService.RestartInstances(input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
jobID := output.JobID
|
|
waitErr := c.waitJob(*jobID)
|
|
if waitErr != nil {
|
|
return waitErr
|
|
}
|
|
_, err = c.WaitInstanceStatus(instanceID, InstanceStatusRunning)
|
|
return err
|
|
}
|
|
|
|
// TerminateInstance
|
|
func (c *client) TerminateInstance(instanceID string) error {
|
|
input := &service.TerminateInstancesInput{Instances: []*string{&instanceID}}
|
|
output, err := c.InstanceService.TerminateInstances(input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
jobID := output.JobID
|
|
waitErr := c.waitJob(*jobID)
|
|
if waitErr != nil {
|
|
return waitErr
|
|
}
|
|
_, err = c.WaitInstanceStatus(instanceID, InstanceStatusTerminated)
|
|
return err
|
|
}
|
|
|
|
func (c *client) waitJob(jobID string) error {
|
|
return WaitJob(c.JobService, jobID, c.OperationTimeout, c.WaitInterval)
|
|
}
|
|
|
|
// WaitInstanceStatus
|
|
func (c *client) WaitInstanceStatus(instanceID string, status string) (*service.Instance, error) {
|
|
return WaitInstanceStatus(c.InstanceService, instanceID, status, c.OperationTimeout, c.WaitInterval)
|
|
}
|
|
|
|
func (c *client) waitInstanceNetwork(instanceID string) (*service.Instance, error) {
|
|
return WaitInstanceNetwork(c.InstanceService, instanceID, c.OperationTimeout, c.WaitInterval)
|
|
}
|