1 Star 0 Fork 0

powerpaas/machine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
vcloudair.go 14.33 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
/*
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
*/
package vmwarevcloudair
import (
"fmt"
"io/ioutil"
"strings"
"github.com/vmware/govcloudair"
"github.com/codegangsta/cli"
"github.com/docker/machine/drivers"
"github.com/docker/machine/log"
"github.com/docker/machine/ssh"
"github.com/docker/machine/state"
"github.com/docker/machine/utils"
)
type Driver struct {
*drivers.BaseDriver
UserName string
UserPassword string
ComputeID string
VDCID string
OrgVDCNet string
EdgeGateway string
PublicIP string
Catalog string
CatalogItem string
DockerPort int
Provision bool
CPUCount int
MemorySize int
VAppID string
}
func init() {
drivers.Register("vmwarevcloudair", &drivers.RegisteredDriver{
New: NewDriver,
GetCreateFlags: GetCreateFlags,
})
}
// GetCreateFlags registers the flags this driver adds to
// "docker hosts create"
func GetCreateFlags() []cli.Flag {
return []cli.Flag{
cli.StringFlag{
EnvVar: "VCLOUDAIR_USERNAME",
Name: "vmwarevcloudair-username",
Usage: "vCloud Air username",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_PASSWORD",
Name: "vmwarevcloudair-password",
Usage: "vCloud Air password",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_COMPUTEID",
Name: "vmwarevcloudair-computeid",
Usage: "vCloud Air Compute ID (if using Dedicated Cloud)",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_VDCID",
Name: "vmwarevcloudair-vdcid",
Usage: "vCloud Air VDC ID",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_ORGVDCNETWORK",
Name: "vmwarevcloudair-orgvdcnetwork",
Usage: "vCloud Air Org VDC Network (Default is <vdcid>-default-routed)",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_EDGEGATEWAY",
Name: "vmwarevcloudair-edgegateway",
Usage: "vCloud Air Org Edge Gateway (Default is <vdcid>)",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_PUBLICIP",
Name: "vmwarevcloudair-publicip",
Usage: "vCloud Air Org Public IP to use",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_CATALOG",
Name: "vmwarevcloudair-catalog",
Usage: "vCloud Air Catalog (default is Public Catalog)",
Value: "Public Catalog",
},
cli.StringFlag{
EnvVar: "VCLOUDAIR_CATALOGITEM",
Name: "vmwarevcloudair-catalogitem",
Usage: "vCloud Air Catalog Item (default is Ubuntu Precise)",
Value: "Ubuntu Server 12.04 LTS (amd64 20150127)",
},
// BoolTFlag is true by default.
cli.BoolTFlag{
EnvVar: "VCLOUDAIR_PROVISION",
Name: "vmwarevcloudair-provision",
Usage: "vCloud Air Install Docker binaries (default is true)",
},
cli.IntFlag{
EnvVar: "VCLOUDAIR_CPU_COUNT",
Name: "vmwarevcloudair-cpu-count",
Usage: "vCloud Air VM Cpu Count (default 1)",
Value: 1,
},
cli.IntFlag{
EnvVar: "VCLOUDAIR_MEMORY_SIZE",
Name: "vmwarevcloudair-memory-size",
Usage: "vCloud Air VM Memory Size in MB (default 2048)",
Value: 2048,
},
cli.IntFlag{
EnvVar: "VCLOUDAIR_SSH_PORT",
Name: "vmwarevcloudair-ssh-port",
Usage: "vCloud Air SSH port",
Value: 22,
},
cli.IntFlag{
EnvVar: "VCLOUDAIR_DOCKER_PORT",
Name: "vmwarevcloudair-docker-port",
Usage: "vCloud Air Docker port",
Value: 2376,
},
}
}
func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) {
inner := drivers.NewBaseDriver(machineName, storePath, caCert, privateKey)
return &Driver{BaseDriver: inner}, nil
}
func (d *Driver) GetSSHHostname() (string, error) {
return d.GetIP()
}
// Driver interface implementation
func (d *Driver) DriverName() string {
return "vmwarevcloudair"
}
func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.UserName = flags.String("vmwarevcloudair-username")
d.UserPassword = flags.String("vmwarevcloudair-password")
d.VDCID = flags.String("vmwarevcloudair-vdcid")
d.PublicIP = flags.String("vmwarevcloudair-publicip")
d.SwarmMaster = flags.Bool("swarm-master")
d.SwarmHost = flags.String("swarm-host")
d.SwarmDiscovery = flags.String("swarm-discovery")
// Check for required Params
if d.UserName == "" || d.UserPassword == "" || d.VDCID == "" || d.PublicIP == "" {
return fmt.Errorf("Please specify vcloudair mandatory params using options: -vmwarevcloudair-username -vmwarevcloudair-password -vmwarevcloudair-vdcid and -vmwarevcloudair-publicip")
}
// If ComputeID is not set we're using a VPC, hence setting ComputeID = VDCID
if flags.String("vmwarevcloudair-computeid") == "" {
d.ComputeID = flags.String("vmwarevcloudair-vdcid")
} else {
d.ComputeID = flags.String("vmwarevcloudair-computeid")
}
// If the Org VDC Network is empty, set it to the default routed network.
if flags.String("vmwarevcloudair-orgvdcnetwork") == "" {
d.OrgVDCNet = flags.String("vmwarevcloudair-vdcid") + "-default-routed"
} else {
d.OrgVDCNet = flags.String("vmwarevcloudair-orgvdcnetwork")
}
// If the Edge Gateway is empty, just set it to the default edge gateway.
if flags.String("vmwarevcloudair-edgegateway") == "" {
d.EdgeGateway = flags.String("vmwarevcloudair-vdcid")
} else {
d.EdgeGateway = flags.String("vmwarevcloudair-edgegateway")
}
d.Catalog = flags.String("vmwarevcloudair-catalog")
d.CatalogItem = flags.String("vmwarevcloudair-catalogitem")
d.DockerPort = flags.Int("vmwarevcloudair-docker-port")
d.SSHUser = "root"
d.SSHPort = flags.Int("vmwarevcloudair-ssh-port")
d.Provision = flags.Bool("vmwarevcloudair-provision")
d.CPUCount = flags.Int("vmwarevcloudair-cpu-count")
d.MemorySize = flags.Int("vmwarevcloudair-memory-size")
return nil
}
func (d *Driver) GetURL() (string, error) {
return fmt.Sprintf("tcp://%s:%d", d.PublicIP, d.DockerPort), nil
}
func (d *Driver) GetIP() (string, error) {
return d.PublicIP, nil
}
func (d *Driver) GetState() (state.State, error) {
p, err := govcloudair.NewClient()
if err != nil {
return state.Error, err
}
log.Debug("Connecting to vCloud Air to fetch vApp Status...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return state.Error, err
}
vapp, err := v.FindVAppByID(d.VAppID)
if err != nil {
return state.Error, err
}
status, err := vapp.GetStatus()
if err != nil {
return state.Error, err
}
if err = p.Disconnect(); err != nil {
return state.Error, err
}
switch status {
case "POWERED_ON":
return state.Running, nil
case "POWERED_OFF":
return state.Stopped, nil
}
return state.None, nil
}
func (d *Driver) PreCreateCheck() error {
return nil
}
func (d *Driver) Create() error {
key, err := d.createSSHKey()
if err != nil {
return err
}
p, err := govcloudair.NewClient()
if err != nil {
return err
}
log.Infof("Connecting to vCloud Air...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return err
}
// Find VDC Network
net, err := v.FindVDCNetwork(d.OrgVDCNet)
if err != nil {
return err
}
// Find our Edge Gateway
edge, err := v.FindEdgeGateway(d.EdgeGateway)
if err != nil {
return err
}
// Get the Org our VDC belongs to
org, err := v.GetVDCOrg()
if err != nil {
return err
}
// Find our Catalog
cat, err := org.FindCatalog(d.Catalog)
if err != nil {
return err
}
// Find our Catalog Item
cati, err := cat.FindCatalogItem(d.CatalogItem)
if err != nil {
return err
}
// Fetch the vApp Template in the Catalog Item
vapptemplate, err := cati.GetVAppTemplate()
if err != nil {
return err
}
// Create a new empty vApp
vapp := govcloudair.NewVApp(p)
log.Infof("Creating a new vApp: %s...", d.MachineName)
// Compose the vApp with ComposeVApp
task, err := vapp.ComposeVApp(net, vapptemplate, d.MachineName, "Container Host created with Docker Host")
if err != nil {
return err
}
// Wait for the creation to be completed
if err = task.WaitTaskCompletion(); err != nil {
return err
}
task, err = vapp.ChangeCPUcount(d.CPUCount)
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
task, err = vapp.ChangeMemorySize(d.MemorySize)
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
sshCustomScript := "echo \"" + strings.TrimSpace(key) + "\" > /root/.ssh/authorized_keys"
task, err = vapp.RunCustomizationScript(d.MachineName, sshCustomScript)
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
task, err = vapp.PowerOn()
if err != nil {
return err
}
log.Infof("Waiting for the VM to power on and run the customization script...")
if err = task.WaitTaskCompletion(); err != nil {
return err
}
log.Infof("Creating NAT and Firewall Rules on %s...", d.EdgeGateway)
task, err = edge.Create1to1Mapping(vapp.VApp.Children.VM[0].NetworkConnectionSection.NetworkConnection.IPAddress, d.PublicIP, d.MachineName)
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
log.Debugf("Disconnecting from vCloud Air...")
if err = p.Disconnect(); err != nil {
return err
}
// Set VAppID with ID of the created VApp
d.VAppID = vapp.VApp.ID
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Remove() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
}
log.Infof("Connecting to vCloud Air...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return err
}
// Find our Edge Gateway
edge, err := v.FindEdgeGateway(d.EdgeGateway)
if err != nil {
return err
}
vapp, err := v.FindVAppByID(d.VAppID)
if err != nil {
log.Infof("Can't find the vApp, assuming it was deleted already...")
return nil
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
log.Infof("Removing NAT and Firewall Rules on %s...", d.EdgeGateway)
task, err := edge.Remove1to1Mapping(vapp.VApp.Children.VM[0].NetworkConnectionSection.NetworkConnection.IPAddress, d.PublicIP)
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
if status == "POWERED_ON" {
// If it's powered on, power it off before deleting
log.Infof("Powering Off %s...", d.MachineName)
task, err = vapp.PowerOff()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
}
log.Debugf("Undeploying %s...", d.MachineName)
task, err = vapp.Undeploy()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
log.Infof("Deleting %s...", d.MachineName)
task, err = vapp.Delete()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
if err = p.Disconnect(); err != nil {
return err
}
return nil
}
func (d *Driver) Start() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
}
log.Infof("Connecting to vCloud Air...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return err
}
vapp, err := v.FindVAppByID(d.VAppID)
if err != nil {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_OFF" {
log.Infof("Starting %s...", d.MachineName)
task, err := vapp.PowerOn()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Stop() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
}
log.Infof("Connecting to vCloud Air...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return err
}
vapp, err := v.FindVAppByID(d.VAppID)
if err != nil {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_ON" {
log.Infof("Shutting down %s...", d.MachineName)
task, err := vapp.Shutdown()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}
d.IPAddress = ""
return nil
}
func (d *Driver) Restart() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
}
log.Infof("Connecting to vCloud Air...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return err
}
vapp, err := v.FindVAppByID(d.VAppID)
if err != nil {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_ON" {
// If it's powered on, restart the machine
log.Infof("Restarting %s...", d.MachineName)
task, err := vapp.Reset()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
} else {
// If it's not powered on, start it.
log.Infof("Docker host %s is powered off, powering it back on...", d.MachineName)
task, err := vapp.PowerOn()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Kill() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
}
log.Infof("Connecting to vCloud Air...")
// Authenticate to vCloud Air
v, err := p.Authenticate(d.UserName, d.UserPassword, d.ComputeID, d.VDCID)
if err != nil {
return err
}
vapp, err := v.FindVAppByID(d.VAppID)
if err != nil {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_ON" {
log.Infof("Stopping %s...", d.MachineName)
task, err := vapp.PowerOff()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}
d.IPAddress = ""
return nil
}
// Helpers
func generateVMName() string {
randomID := utils.TruncateID(utils.GenerateRandomID())
return fmt.Sprintf("docker-host-%s", randomID)
}
func (d *Driver) createSSHKey() (string, error) {
if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
return "", err
}
publicKey, err := ioutil.ReadFile(d.publicSSHKeyPath())
if err != nil {
return "", err
}
return string(publicKey), nil
}
func (d *Driver) publicSSHKeyPath() string {
return d.GetSSHKeyPath() + ".pub"
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/powerpaas/machine.git
git@gitee.com:powerpaas/machine.git
powerpaas
machine
machine
v0.3.1

搜索帮助