mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 14:19:49 +08:00
Merge branch 'release/2.0.0' of ssh://git.yunion.io/~qiujian/onecloud into hotfix/qj-misc-bugfix-20180808
This commit is contained in:
Generated
+23
-1
@@ -544,6 +544,28 @@
|
||||
packages = ["codec"]
|
||||
revision = "f3cacc17c85ecb7f1b6a9e373ee85d1480919868"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/vmware/govmomi"
|
||||
packages = [
|
||||
".",
|
||||
"nfc",
|
||||
"object",
|
||||
"property",
|
||||
"session",
|
||||
"task",
|
||||
"view",
|
||||
"vim25",
|
||||
"vim25/debug",
|
||||
"vim25/methods",
|
||||
"vim25/mo",
|
||||
"vim25/progress",
|
||||
"vim25/soap",
|
||||
"vim25/types",
|
||||
"vim25/xml"
|
||||
]
|
||||
revision = "bbd99532a768d2fe369079ceda730e30726ae1a6"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/yunionio/jsonutils"
|
||||
packages = ["."]
|
||||
@@ -882,6 +904,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "ac275c3d7f14e4a959b3029058a3bb40bb016860ad0e9794e7a396ba33e62048"
|
||||
inputs-digest = "1fdd79d4d8791f7e87a3740b3807ea84f6306ecac3095d32a1ccf39b48be1f18"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
@@ -80,3 +80,8 @@
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/vmware/govmomi"
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/structarg"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun/shell"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
"github.com/yunionio/structarg"
|
||||
|
||||
_ "github.com/yunionio/onecloud/pkg/util/aliyun/shell"
|
||||
)
|
||||
|
||||
type BaseOptions struct {
|
||||
@@ -35,7 +37,7 @@ func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
type HelpOptions struct {
|
||||
SUBCOMMAND string `help:"sub-command name"`
|
||||
}
|
||||
shell.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
|
||||
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
|
||||
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -44,7 +46,7 @@ func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
return nil
|
||||
}
|
||||
})
|
||||
for _, v := range shell.CommandTable {
|
||||
for _, v := range shellutils.CommandTable {
|
||||
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
|
||||
@@ -4,17 +4,17 @@ import (
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/util/printjson"
|
||||
"github.com/yunionio/onecloud/pkg/util/printutils"
|
||||
)
|
||||
|
||||
func printList(list *modules.ListResult, columns []string) {
|
||||
printjson.PrintList(list, columns)
|
||||
printutils.PrintJSONList(list, columns)
|
||||
}
|
||||
|
||||
func printObject(obj jsonutils.JSONObject) {
|
||||
printjson.PrintObject(obj)
|
||||
printutils.PrintJSONObject(obj)
|
||||
}
|
||||
|
||||
func printBatchResults(results []modules.SubmitResult, columns []string) {
|
||||
printjson.PrintBatchResults(results, columns)
|
||||
printutils.PrintJSONBatchResults(results, columns)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/structarg"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/util/esxi"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
|
||||
_ "github.com/yunionio/onecloud/pkg/util/esxi/shell"
|
||||
)
|
||||
|
||||
type BaseOptions struct {
|
||||
Help bool `help:"Show help"`
|
||||
Host string `help:"Host IP or NAME" default:"$VMWARE_HOST"`
|
||||
Port int `help:"Service port" default:"$VMWARE_PORT"`
|
||||
Account string `help:"VCenter or ESXi Account" default:"$VMWARE_ACCOUNT"`
|
||||
Password string `help:"Password" default:"$VMWARE_PASSWORD"`
|
||||
SUBCOMMAND string `help:"aliyuncli subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(&BaseOptions{},
|
||||
"govmcli",
|
||||
"Command-line interface to VMware VSphere Webservice API.",
|
||||
`See "govmcli help COMMAND" for help on a specific command.`)
|
||||
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
subcmd := parse.GetSubcommand()
|
||||
if subcmd == nil {
|
||||
return nil, fmt.Errorf("No subcommand argument.")
|
||||
}
|
||||
type HelpOptions struct {
|
||||
SUBCOMMAND string `help:"sub-command name"`
|
||||
}
|
||||
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
|
||||
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
|
||||
if e != nil {
|
||||
return e
|
||||
} else {
|
||||
fmt.Print(helpstr)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
for _, v := range shellutils.CommandTable {
|
||||
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
return parse, nil
|
||||
}
|
||||
|
||||
func showErrorAndExit(e error) {
|
||||
log.Errorf("%s", e)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClient(options *BaseOptions) (*esxi.SESXiClient, error) {
|
||||
if len(options.Host) == 0 {
|
||||
return nil, fmt.Errorf("Missing host")
|
||||
}
|
||||
|
||||
if len(options.Account) == 0 {
|
||||
return nil, fmt.Errorf("Missing account")
|
||||
}
|
||||
|
||||
if len(options.Password) == 0 {
|
||||
return nil, fmt.Errorf("Missing password")
|
||||
}
|
||||
|
||||
return esxi.NewESXiClient("", "", options.Host, options.Port, options.Account, options.Password)
|
||||
}
|
||||
|
||||
func main() {
|
||||
parser, e := getSubcommandParser()
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = parser.ParseArgs(os.Args[1:], false)
|
||||
options := parser.Options().(*BaseOptions)
|
||||
|
||||
if options.Help {
|
||||
fmt.Print(parser.HelpString())
|
||||
} else {
|
||||
subcmd := parser.GetSubcommand()
|
||||
subparser := subcmd.GetSubParser()
|
||||
if e != nil {
|
||||
if subparser != nil {
|
||||
fmt.Print(subparser.Usage())
|
||||
} else {
|
||||
fmt.Print(parser.Usage())
|
||||
}
|
||||
showErrorAndExit(e)
|
||||
} else {
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
var esxicli *esxi.SESXiClient
|
||||
esxicli, e = newClient(options)
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = subcmd.Invoke(esxicli, suboptions)
|
||||
}
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/appctx"
|
||||
"github.com/yunionio/onecloud/pkg/appsrv"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
func AddModelDispatcher(prefix string, app *appsrv.Application, manager IModelDispatchHandler) {
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/appsrv"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
type IMiddlewareFilter interface {
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/appctx"
|
||||
"github.com/yunionio/onecloud/pkg/appsrv"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
func AddJointModelDispatcher(prefix string, app *appsrv.Application, manager IJointModelDispatchHandler) {
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/appsrv"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/appsrv"
|
||||
"github.com/yunionio/pkg/gotypes"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/util/filterclause"
|
||||
"github.com/yunionio/onecloud/pkg/util/httputils"
|
||||
"github.com/yunionio/pkg/gotypes"
|
||||
"github.com/yunionio/pkg/util/filterclause"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
)
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/util/stringutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/appctx"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/util/httputils"
|
||||
"github.com/yunionio/pkg/util/reflectutils"
|
||||
"github.com/yunionio/pkg/util/stringutils"
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/reflectutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/timeutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
@@ -2,7 +2,9 @@ package cloudprovider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type ICloudProviderFactory interface {
|
||||
@@ -40,6 +42,7 @@ func GetProvider(providerId, providerName, accessUrl, account, secret, provider
|
||||
if ok {
|
||||
return factory.GetProvider(providerId, providerName, accessUrl, account, secret)
|
||||
}
|
||||
log.Errorf("Provider %s not registerd", provider)
|
||||
return nil, fmt.Errorf("No such provider %s", provider)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,3 +15,5 @@ var ErrNotFound = errors.New("id not found")
|
||||
var ErrDuplicateId = errors.New("duplicate id")
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
var ErrTimeout = errors.New("timeout")
|
||||
var ErrNotImplemented = errors.New("Not implemented")
|
||||
var ErrNotSupported = errors.New("Not supported")
|
||||
|
||||
@@ -130,7 +130,7 @@ type ICloudVM interface {
|
||||
GetEIP() ICloudEIP
|
||||
|
||||
// GetStatus() string
|
||||
GetRemoteStatus() string
|
||||
// GetRemoteStatus() string
|
||||
|
||||
GetVcpuCount() int8
|
||||
GetVmemSizeMB() int //MB
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/seclib"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
@@ -240,25 +240,3 @@ func (self *SAliyunGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Contex
|
||||
guest.SaveDeployInfo(ctx, task.GetUserCred(), data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliyunGuestDriver) GetGuestVncInfo(userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
|
||||
ihost, err := host.GetIHost()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iVM, err := ihost.GetIVMById(guest.ExternalId)
|
||||
if err != nil {
|
||||
log.Errorf("cannot find vm %s %s", iVM, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := iVM.GetVNCInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dataDict := data.(*jsonutils.JSONDict)
|
||||
|
||||
return dataDict, nil
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package guestdrivers
|
||||
|
||||
import (
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
@@ -19,9 +16,3 @@ func init() {
|
||||
func (self *SESXiGuestDriver) GetHypervisor() string {
|
||||
return models.HYPERVISOR_ESXI
|
||||
}
|
||||
|
||||
func (self *SESXiGuestDriver) GetGuestVncInfo(userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
|
||||
data := jsonutils.NewDict()
|
||||
// TODO
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -112,6 +112,28 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncstatusOnHost(ctx context.
|
||||
return nil, err
|
||||
}
|
||||
body := jsonutils.NewDict()
|
||||
body.Add(jsonutils.NewString(ivm.GetRemoteStatus()), "status")
|
||||
body.Add(jsonutils.NewString(ivm.GetStatus()), "status")
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizedGuestDriver) GetGuestVncInfo(userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
|
||||
ihost, err := host.GetIHost()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iVM, err := ihost.GetIVMById(guest.ExternalId)
|
||||
if err != nil {
|
||||
log.Errorf("cannot find vm %s %s", iVM, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := iVM.GetVNCInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dataDict := data.(*jsonutils.JSONDict)
|
||||
|
||||
return dataDict, nil
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"regexp"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/util/timeutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/timeutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
@@ -24,8 +25,8 @@ const (
|
||||
CLOUD_PROVIDER_START_SYNC = "start_sync"
|
||||
CLOUD_PROVIDER_SYNCING = "syncing"
|
||||
|
||||
CLOUD_PROVIDER_DRIVER_VMWARE = "VMware"
|
||||
CLOUD_PROVIDER_DRIVER_ALIYUN = "Aliyun"
|
||||
CLOUD_PROVIDER_VMWARE = "VMware"
|
||||
CLOUD_PROVIDER_ALIYUN = "Aliyun"
|
||||
)
|
||||
|
||||
type SCloudproviderManager struct {
|
||||
@@ -195,10 +196,9 @@ func (self *SCloudprovider) PerformUpdateCredential(ctx context.Context, userCre
|
||||
q := self.GetModelManager().Query()
|
||||
q = q.Equals("access_url", accessUrl)
|
||||
q = q.Equals("account", account)
|
||||
q = q.Equals("secret", secret)
|
||||
q = q.NotEquals("id", self.Id)
|
||||
if q.Count() > 0 {
|
||||
return nil, httperrors.NewConflictError("Access url and account and ")
|
||||
return nil, httperrors.NewConflictError("Access url and account conflict")
|
||||
}
|
||||
}
|
||||
if len(secret) > 0 {
|
||||
@@ -292,14 +292,6 @@ func (manager *SCloudproviderManager) FetchCloudproviderByIdOrName(providerId st
|
||||
return providerObj.(*SCloudprovider)
|
||||
}
|
||||
|
||||
/*func (manager *SCloudproviderManager) GetDriverByManagerId(managerId string) (cloudprovider.ICloudProvider, error) {
|
||||
provider := manager.FetchCloudproviderById(managerId)
|
||||
if provider == nil {
|
||||
return nil, fmt.Errorf("no valid cloud provider")
|
||||
}
|
||||
return provider.GetDriver()
|
||||
}*/
|
||||
|
||||
type SCloudproviderUsage struct {
|
||||
HostCount int
|
||||
VpcCount int
|
||||
@@ -347,3 +339,55 @@ func (self *SCloudprovider) GetExtraDetails(ctx context.Context, userCred mcclie
|
||||
extra := self.SEnabledStatusStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
return self.getMoreDetails(extra)
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderManager) InitializeData() error {
|
||||
// move vmware info from vcenter to cloudprovider
|
||||
vcenters := make([]SVCenter, 0)
|
||||
q := VCenterManager.Query()
|
||||
err := db.FetchModelObjects(VCenterManager, q, &vcenters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, vc := range vcenters {
|
||||
_, err := CloudproviderManager.FetchById(vc.Id)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = manager.migrateVCenterInfo(&vc)
|
||||
if err != nil {
|
||||
log.Errorf("migrateVcenterInfo fail %s", err)
|
||||
return err
|
||||
}
|
||||
_, err = VCenterManager.TableSpec().Update(&vc, func() error {
|
||||
return vc.MarkDelete()
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("delete vcenter record fail %s", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Errorf("fetch cloudprovider fail %s", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Debugf("vcenter info has been migrate into cloudprovider")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderManager) migrateVCenterInfo(vc *SVCenter) error {
|
||||
cp := SCloudprovider{}
|
||||
cp.SetModelManager(manager)
|
||||
|
||||
cp.Id = vc.Id
|
||||
cp.Name = db.GenerateName(manager, "", vc.Name)
|
||||
cp.Status = vc.Status
|
||||
cp.AccessUrl = fmt.Sprintf("https://%s:%d", vc.Hostname, vc.Port)
|
||||
cp.Account = vc.Account
|
||||
cp.Secret = vc.Password
|
||||
cp.LastSync = vc.LastSync
|
||||
cp.Sysinfo = vc.Sysinfo
|
||||
cp.Provider = CLOUD_PROVIDER_VMWARE
|
||||
|
||||
return manager.TableSpec().Insert(&cp)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/pkg/util/fileutils"
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type IGuestDriver interface {
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SHostschedtagManager struct {
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
func InitDB() error {
|
||||
for _, manager := range []db.IModelManager{
|
||||
CloudproviderManager,
|
||||
CloudregionManager,
|
||||
ZoneManager,
|
||||
VpcManager,
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
)
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/secrules"
|
||||
"github.com/yunionio/pkg/util/stringutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SVCenterManager struct {
|
||||
@@ -17,7 +17,7 @@ type SVCenterManager struct {
|
||||
var VCenterManager *SVCenterManager
|
||||
|
||||
func init() {
|
||||
VCenterManager = &SVCenterManager{SEnabledStatusStandaloneResourceBaseManager: db.NewEnabledStatusStandaloneResourceBaseManager(SCloudprovider{}, "vcenters_tbl", "vcenter", "vcenters")}
|
||||
VCenterManager = &SVCenterManager{SEnabledStatusStandaloneResourceBaseManager: db.NewEnabledStatusStandaloneResourceBaseManager(SVCenter{}, "vcenters_tbl", "vcenter", "vcenters")}
|
||||
}
|
||||
|
||||
type SVCenter struct {
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
_ "github.com/yunionio/onecloud/pkg/compute/guestdrivers"
|
||||
|
||||
_ "github.com/yunionio/onecloud/pkg/util/aliyun/provider"
|
||||
_ "github.com/yunionio/onecloud/pkg/util/esxi/provider"
|
||||
)
|
||||
|
||||
func StartService() {
|
||||
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/notifyclient"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
type GuestBatchCreateTask struct {
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
|
||||
json "github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/appctx"
|
||||
"github.com/yunionio/onecloud/pkg/appsrv"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -114,4 +114,4 @@ func NewYunionAgentManager(keyword, keywordPlural string, columns, adminColumns
|
||||
adminColumns: adminColumns,
|
||||
serviceType: "yunionagent"},
|
||||
Keyword: keyword, KeywordPlural: keywordPlural}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ var (
|
||||
|
||||
func init() {
|
||||
VCenters = NewComputeManager("vcenter", "vcenters",
|
||||
[]string{"ID", "Name", "Hostname", "Status", "Version", "Host_count"},
|
||||
[]string{"ID", "Name", "access_url", "Status", "Version", "Host_count", "Provider"},
|
||||
[]string{})
|
||||
|
||||
registerCompute(&VCenters)
|
||||
|
||||
Vendored
+3
-3
@@ -21,9 +21,9 @@ func getUpdate(d []interface{}) ([]string, error) {
|
||||
|
||||
func defaultSyncItems() []cache.CachedItem {
|
||||
return []cache.CachedItem{
|
||||
//newGlanceCache(),
|
||||
//newNetworkCache(),
|
||||
//newNetworksDataCache(),
|
||||
//newGlanceCache(),
|
||||
//newNetworkCache(),
|
||||
//newNetworksDataCache(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
const (
|
||||
CLOUD_PROVIDER_ALIYUN = "Aliyun"
|
||||
CLOUD_PROVIDER_ALIYUN = models.CLOUD_PROVIDER_ALIYUN
|
||||
CLOUD_PROVIDER_ALIYUN_CN = "阿里云"
|
||||
|
||||
ALIYUN_DEFAULT_REGION = "cn-hangzhou"
|
||||
|
||||
@@ -6,11 +6,12 @@ import (
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/pkg/util/osprofile"
|
||||
"github.com/yunionio/pkg/util/seclib"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -291,6 +292,7 @@ func (self *SInstance) Refresh() error {
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
/*
|
||||
func (self *SInstance) GetRemoteStatus() string {
|
||||
// Running:运行中
|
||||
//Starting:启动中
|
||||
@@ -309,6 +311,7 @@ func (self *SInstance) GetRemoteStatus() string {
|
||||
return cloudprovider.CloudVMStatusOther
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func (self *SInstance) GetHypervisor() string {
|
||||
return models.HYPERVISOR_ALIYUN
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -12,7 +13,7 @@ func init() {
|
||||
Offset int `help:"List offset"`
|
||||
Limit int `help:"List limit"`
|
||||
}
|
||||
R(&DiskListOptions{}, "disk-list", "List disks", func(cli *aliyun.SRegion, args *DiskListOptions) error {
|
||||
shellutils.R(&DiskListOptions{}, "disk-list", "List disks", func(cli *aliyun.SRegion, args *DiskListOptions) error {
|
||||
disks, total, e := cli.GetDisks(args.Instance, args.Zone, args.Category, nil, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -13,7 +14,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&ImageListOptions{}, "image-list", "List images", func(cli *aliyun.SRegion, args *ImageListOptions) error {
|
||||
shellutils.R(&ImageListOptions{}, "image-list", "List images", func(cli *aliyun.SRegion, args *ImageListOptions) error {
|
||||
images, total, e := cli.GetImages(aliyun.ImageStatusType(args.Status), aliyun.ImageOwnerType(args.Owner), args.Id, args.Name, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -25,7 +26,7 @@ func init() {
|
||||
type ImageDeleteOptions struct {
|
||||
ID string `help:"ID or Name to delete"`
|
||||
}
|
||||
R(&ImageDeleteOptions{}, "image-delete", "Delete image", func(cli *aliyun.SRegion, args *ImageDeleteOptions) error {
|
||||
shellutils.R(&ImageDeleteOptions{}, "image-delete", "Delete image", func(cli *aliyun.SRegion, args *ImageDeleteOptions) error {
|
||||
return cli.DeleteImage(args.ID)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package shell
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -12,7 +13,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&InstanceListOptions{}, "instance-list", "List intances", func(cli *aliyun.SRegion, args *InstanceListOptions) error {
|
||||
shellutils.R(&InstanceListOptions{}, "instance-list", "List intances", func(cli *aliyun.SRegion, args *InstanceListOptions) error {
|
||||
instances, total, e := cli.GetInstances(args.Zone, args.Id, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -32,7 +33,7 @@ func init() {
|
||||
PASSWD string `help:"password"`
|
||||
PublicKey string `help:"PublicKey"`
|
||||
}
|
||||
R(&InstanceCrateOptions{}, "instance-create", "Create a instance", func(cli *aliyun.SRegion, args *InstanceCrateOptions) error {
|
||||
shellutils.R(&InstanceCrateOptions{}, "instance-create", "Create a instance", func(cli *aliyun.SRegion, args *InstanceCrateOptions) error {
|
||||
instance, e := cli.CreateInstanceSimple(args.NAME, args.IMAGE, args.CPU, args.MEMORYGB, args.STORAGE, args.Disk, args.VSWITCH, args.PASSWD, args.PublicKey)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -44,7 +45,7 @@ func init() {
|
||||
type InstanceOperationOptions struct {
|
||||
ID string `help:"instance ID"`
|
||||
}
|
||||
R(&InstanceOperationOptions{}, "instance-start", "Start a instance", func(cli *aliyun.SRegion, args *InstanceOperationOptions) error {
|
||||
shellutils.R(&InstanceOperationOptions{}, "instance-start", "Start a instance", func(cli *aliyun.SRegion, args *InstanceOperationOptions) error {
|
||||
err := cli.StartVM(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -52,7 +53,7 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&InstanceOperationOptions{}, "instance-vnc", "Get a instance VNC url", func(cli *aliyun.SRegion, args *InstanceOperationOptions) error {
|
||||
shellutils.R(&InstanceOperationOptions{}, "instance-vnc", "Get a instance VNC url", func(cli *aliyun.SRegion, args *InstanceOperationOptions) error {
|
||||
url, err := cli.GetInstanceVNCUrl(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -65,14 +66,14 @@ func init() {
|
||||
ID string `help:"instance ID"`
|
||||
Force bool `help:"Force stop instance"`
|
||||
}
|
||||
R(&InstanceStopOptions{}, "instance-stop", "Stop a instance", func(cli *aliyun.SRegion, args *InstanceStopOptions) error {
|
||||
shellutils.R(&InstanceStopOptions{}, "instance-stop", "Stop a instance", func(cli *aliyun.SRegion, args *InstanceStopOptions) error {
|
||||
err := cli.StopVM(args.ID, args.Force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
R(&InstanceOperationOptions{}, "instance-delete", "Delete a instance", func(cli *aliyun.SRegion, args *InstanceOperationOptions) error {
|
||||
shellutils.R(&InstanceOperationOptions{}, "instance-delete", "Delete a instance", func(cli *aliyun.SRegion, args *InstanceOperationOptions) error {
|
||||
err := cli.DeleteVM(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -2,12 +2,13 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type InstanceTypeListOptions struct {
|
||||
}
|
||||
R(&InstanceTypeListOptions{}, "instance-type-list", "List intance types", func(cli *aliyun.SRegion, args *InstanceTypeListOptions) error {
|
||||
shellutils.R(&InstanceTypeListOptions{}, "instance-type-list", "List intance types", func(cli *aliyun.SRegion, args *InstanceTypeListOptions) error {
|
||||
instanceTypes, e := cli.GetInstanceTypes()
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -22,7 +23,7 @@ func init() {
|
||||
GPU int `help:"GPU size"`
|
||||
Zone string `help:"Test in zone"`
|
||||
}
|
||||
R(&InstanceMatchOptions{}, "instance-type-select", "Select matching instance types", func(cli *aliyun.SRegion, args *InstanceMatchOptions) error {
|
||||
shellutils.R(&InstanceMatchOptions{}, "instance-type-select", "Select matching instance types", func(cli *aliyun.SRegion, args *InstanceMatchOptions) error {
|
||||
instanceTypes, e := cli.GetMatchInstanceTypes(args.CPU, args.MEM, args.GPU, args.Zone)
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -9,7 +10,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&KeyPairListOptions{}, "keypair-list", "List keypairs", func(cli *aliyun.SRegion, args *KeyPairListOptions) error {
|
||||
shellutils.R(&KeyPairListOptions{}, "keypair-list", "List keypairs", func(cli *aliyun.SRegion, args *KeyPairListOptions) error {
|
||||
keypairs, total, e := cli.GetKeypairs("", "", args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -22,7 +23,7 @@ func init() {
|
||||
NAME string `help:"Name of new keypair"`
|
||||
PUBKEY string `help:"Public key string"`
|
||||
}
|
||||
R(&KeyPairImportOptions{}, "keypair-import", "Import a keypair", func(cli *aliyun.SRegion, args *KeyPairImportOptions) error {
|
||||
shellutils.R(&KeyPairImportOptions{}, "keypair-import", "Import a keypair", func(cli *aliyun.SRegion, args *KeyPairImportOptions) error {
|
||||
keypair, err := cli.ImportKeypair(args.NAME, args.PUBKEY)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
osslib "github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
type progressListener struct {
|
||||
@@ -40,7 +41,7 @@ func str2AclType(aclStr string) osslib.ACLType {
|
||||
func init() {
|
||||
type OssListOptions struct {
|
||||
}
|
||||
R(&OssListOptions{}, "oss-list", "List OSS buckets", func(cli *aliyun.SRegion, args *OssListOptions) error {
|
||||
shellutils.R(&OssListOptions{}, "oss-list", "List OSS buckets", func(cli *aliyun.SRegion, args *OssListOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -57,7 +58,7 @@ func init() {
|
||||
BUCKET string `help:"bucket name"`
|
||||
}
|
||||
|
||||
R(&OssListBucketOptions{}, "oss-list-bucket", "List content of a OSS bucket", func(cli *aliyun.SRegion, args *OssListBucketOptions) error {
|
||||
shellutils.R(&OssListBucketOptions{}, "oss-list-bucket", "List content of a OSS bucket", func(cli *aliyun.SRegion, args *OssListBucketOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -74,7 +75,7 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&OssListBucketOptions{}, "oss-create-bucket", "Create a OSS bucket", func(cli *aliyun.SRegion, args *OssListBucketOptions) error {
|
||||
shellutils.R(&OssListBucketOptions{}, "oss-create-bucket", "Create a OSS bucket", func(cli *aliyun.SRegion, args *OssListBucketOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -93,7 +94,7 @@ func init() {
|
||||
Progress bool `help:"show progress"`
|
||||
Acl string `help:"Object ACL" choices:"private|public-read|public-rw"`
|
||||
}
|
||||
R(&OssUploadOptions{}, "oss-upload", "Upload a file to a OSS bucket", func(cli *aliyun.SRegion, args *OssUploadOptions) error {
|
||||
shellutils.R(&OssUploadOptions{}, "oss-upload", "Upload a file to a OSS bucket", func(cli *aliyun.SRegion, args *OssUploadOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -120,7 +121,7 @@ func init() {
|
||||
KEY string `help:"object key"`
|
||||
ACL string `help:"ACL" choices:"private|public-read|public-rw"`
|
||||
}
|
||||
R(&OssObjectAclOptions{}, "oss-set-acl", "Set acl for a object", func(cli *aliyun.SRegion, args *OssObjectAclOptions) error {
|
||||
shellutils.R(&OssObjectAclOptions{}, "oss-set-acl", "Set acl for a object", func(cli *aliyun.SRegion, args *OssObjectAclOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -138,7 +139,7 @@ func init() {
|
||||
KEY string `help:"Object key"`
|
||||
}
|
||||
|
||||
R(&OssDeleteOptions{}, "oss-delete", "Delete a file from a OSS bucket", func(cli *aliyun.SRegion, args *OssDeleteOptions) error {
|
||||
shellutils.R(&OssDeleteOptions{}, "oss-delete", "Delete a file from a OSS bucket", func(cli *aliyun.SRegion, args *OssDeleteOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package shell
|
||||
|
||||
import "github.com/yunionio/onecloud/pkg/util/printutils"
|
||||
|
||||
func printList(data interface{}, total, offset, limit int, columns []string) {
|
||||
printutils.PrintInterfaceList(data, total, offset, limit, columns)
|
||||
}
|
||||
|
||||
func printObject(obj interface{}) {
|
||||
printutils.PrintInterfaceObject(obj)
|
||||
}
|
||||
@@ -2,12 +2,13 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type RegionListOptions struct {
|
||||
}
|
||||
R(&RegionListOptions{}, "region-list", "List regions", func(cli *aliyun.SRegion, args *RegionListOptions) error {
|
||||
shellutils.R(&RegionListOptions{}, "region-list", "List regions", func(cli *aliyun.SRegion, args *RegionListOptions) error {
|
||||
regions := cli.GetClient().GetRegions()
|
||||
printList(regions, 0, 0, 0, nil)
|
||||
return nil
|
||||
|
||||
@@ -3,6 +3,7 @@ package shell
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -10,7 +11,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&RouteTableListOptions{}, "routetable-list", "List routetables", func(cli *aliyun.SRegion, args *RouteTableListOptions) error {
|
||||
shellutils.R(&RouteTableListOptions{}, "routetable-list", "List routetables", func(cli *aliyun.SRegion, args *RouteTableListOptions) error {
|
||||
routetables, total, e := cli.GetRouteTables(nil, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -22,7 +23,7 @@ func init() {
|
||||
type RouteTableShowOptions struct {
|
||||
ID string `help:"ID or name of routetable"`
|
||||
}
|
||||
R(&RouteTableShowOptions{}, "routetable-show", "Show routetable", func(cli *aliyun.SRegion, args *RouteTableShowOptions) error {
|
||||
shellutils.R(&RouteTableShowOptions{}, "routetable-show", "Show routetable", func(cli *aliyun.SRegion, args *RouteTableShowOptions) error {
|
||||
routetables, _, e := cli.GetRouteTables([]string{args.ID}, 0, 1)
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -10,7 +11,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&SecurityGroupListOptions{}, "security-group-list", "List security group", func(cli *aliyun.SRegion, args *SecurityGroupListOptions) error {
|
||||
shellutils.R(&SecurityGroupListOptions{}, "security-group-list", "List security group", func(cli *aliyun.SRegion, args *SecurityGroupListOptions) error {
|
||||
secgrps, total, e := cli.GetSecurityGroups(args.VpcId, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -22,7 +23,7 @@ func init() {
|
||||
type SecurityGroupShowOptions struct {
|
||||
ID string `help:"ID or name of security group"`
|
||||
}
|
||||
R(&SecurityGroupShowOptions{}, "security-group-show", "Show details of a security group", func(cli *aliyun.SRegion, args *SecurityGroupShowOptions) error {
|
||||
shellutils.R(&SecurityGroupShowOptions{}, "security-group-show", "Show details of a security group", func(cli *aliyun.SRegion, args *SecurityGroupShowOptions) error {
|
||||
secgrp, err := cli.GetSecurityGroupDetails(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package shell
|
||||
|
||||
import "github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type TaskListOptions struct {
|
||||
@@ -9,7 +12,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&TaskListOptions{}, "task-list", "List tasks", func(cli *aliyun.SRegion, args *TaskListOptions) error {
|
||||
shellutils.R(&TaskListOptions{}, "task-list", "List tasks", func(cli *aliyun.SRegion, args *TaskListOptions) error {
|
||||
tasks, total, err := cli.GetTasks(aliyun.TaskActionType(args.TYPE), args.Task, args.Offset, args.Limit)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -9,7 +10,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&VpcListOptions{}, "vpc-list", "List vpcs", func(cli *aliyun.SRegion, args *VpcListOptions) error {
|
||||
shellutils.R(&VpcListOptions{}, "vpc-list", "List vpcs", func(cli *aliyun.SRegion, args *VpcListOptions) error {
|
||||
vpcs, total, e := cli.GetVpcs(nil, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -9,7 +10,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&VRouterListOptions{}, "vrouter-list", "List vrouters", func(cli *aliyun.SRegion, args *VRouterListOptions) error {
|
||||
shellutils.R(&VRouterListOptions{}, "vrouter-list", "List vrouters", func(cli *aliyun.SRegion, args *VRouterListOptions) error {
|
||||
vrouters, total, e := cli.GetVRouters(args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -9,7 +10,7 @@ func init() {
|
||||
Limit int `help:"page size"`
|
||||
Offset int `help:"page offset"`
|
||||
}
|
||||
R(&VSwitchListOptions{}, "vswitch-list", "List vswitches", func(cli *aliyun.SRegion, args *VSwitchListOptions) error {
|
||||
shellutils.R(&VSwitchListOptions{}, "vswitch-list", "List vswitches", func(cli *aliyun.SRegion, args *VSwitchListOptions) error {
|
||||
vswitches, total, e := cli.GetVSwitches(nil, "", args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -10,7 +11,7 @@ func init() {
|
||||
// ChargeType string `help:"charge type" choices:"PrePaid|PostPaid" default:"PrePaid"`
|
||||
// SpotStrategy string `help:"Spot strategy, NoSpot|SpotWithPriceLimit|SpotAsPriceGo" choices:"NoSpot|SpotWithPriceLimit|SpotAsPriceGo" default:"NoSpot"`
|
||||
}
|
||||
R(&ZoneListOptions{}, "zone-list", "List zones", func(cli *aliyun.SRegion, args *ZoneListOptions) error {
|
||||
shellutils.R(&ZoneListOptions{}, "zone-list", "List zones", func(cli *aliyun.SRegion, args *ZoneListOptions) error {
|
||||
zones, e := cli.GetIZones()
|
||||
if e != nil {
|
||||
return e
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/auth"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
)
|
||||
|
||||
type SStoragecache struct {
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
var DATACENTER_PROPS = []string{"name", "parent", "datastore"}
|
||||
|
||||
type SDatacenter struct {
|
||||
SManagedObject
|
||||
|
||||
ihosts []cloudprovider.ICloudHost
|
||||
istorages []cloudprovider.ICloudStorage
|
||||
|
||||
Name string
|
||||
}
|
||||
|
||||
func newDatacenter(manager *SESXiClient, dc *mo.Datacenter) *SDatacenter {
|
||||
obj := SDatacenter{SManagedObject: newManagedObject(manager, dc, nil)}
|
||||
obj.datacenter = &obj
|
||||
return &obj
|
||||
}
|
||||
|
||||
func (dc *SDatacenter) getDatacenter() *mo.Datacenter {
|
||||
return dc.object.(*mo.Datacenter)
|
||||
}
|
||||
|
||||
func (dc *SDatacenter) scanHosts() error {
|
||||
if dc.ihosts == nil {
|
||||
var hosts []mo.HostSystem
|
||||
err := dc.manager.scanMObjects(dc.object.Entity().Self, HOST_SYSTEM_PROPS, &hosts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dc.ihosts = make([]cloudprovider.ICloudHost, len(hosts))
|
||||
for i := 0; i < len(hosts); i += 1 {
|
||||
dc.ihosts[i] = NewHost(dc.manager, &hosts[i], dc)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dc *SDatacenter) GetIHosts() ([]cloudprovider.ICloudHost, error) {
|
||||
err := dc.scanHosts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dc.ihosts, nil
|
||||
}
|
||||
|
||||
func (dc *SDatacenter) scanDatastores() error {
|
||||
if dc.istorages == nil {
|
||||
stores := make([]mo.Datastore, 0)
|
||||
dsList := dc.getDatacenter().Datastore
|
||||
for i := 0; i < len(dsList); i += 1 {
|
||||
var ds mo.Datastore
|
||||
err := dc.manager.reference2Object(dsList[i], DATASTORE_PROPS, &ds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stores = append(stores, ds)
|
||||
}
|
||||
dc.istorages = make([]cloudprovider.ICloudStorage, len(stores))
|
||||
for i := 0; i < len(stores); i += 1 {
|
||||
dc.istorages[i] = NewDatastore(dc.manager, &stores[i], dc)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dc *SDatacenter) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
err := dc.scanDatastores()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dc.istorages, nil
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
)
|
||||
|
||||
var HOST_SYSTEM_PROPS = []string{"name", "parent", "summary", "config", "hardware", "vm"}
|
||||
|
||||
type SHostNicInfo struct {
|
||||
Dev string
|
||||
Driver string
|
||||
Mac string
|
||||
Index int
|
||||
LinkUp bool
|
||||
IpAddr string
|
||||
Mtu int
|
||||
NicType string
|
||||
}
|
||||
|
||||
type SHostStorageAdapterInfo struct {
|
||||
Device string
|
||||
Model string
|
||||
Driver string
|
||||
Pci string
|
||||
Drivers []SHostStorageDriverInfo
|
||||
Enclosure int
|
||||
}
|
||||
|
||||
type SHostStorageDriverInfo struct {
|
||||
CN string
|
||||
Name string
|
||||
Model string
|
||||
Vendor string
|
||||
Revision string
|
||||
Status string
|
||||
SSD bool
|
||||
Dev string
|
||||
Size int
|
||||
}
|
||||
|
||||
type SHostStorageEnclosureInfo struct {
|
||||
CN string
|
||||
Name string
|
||||
Model string
|
||||
Vendor string
|
||||
Revision string
|
||||
Status string
|
||||
}
|
||||
|
||||
type SHost struct {
|
||||
SManagedObject
|
||||
|
||||
nicInfo []SHostNicInfo
|
||||
storageInfo []SHostStorageAdapterInfo
|
||||
|
||||
vms []cloudprovider.ICloudVM
|
||||
}
|
||||
|
||||
func NewHost(manager *SESXiClient, host *mo.HostSystem, dc *SDatacenter) *SHost {
|
||||
return &SHost{SManagedObject: newManagedObject(manager, host, dc)}
|
||||
}
|
||||
|
||||
func (self *SHost) getHostSystem() *mo.HostSystem {
|
||||
return self.object.(*mo.HostSystem)
|
||||
}
|
||||
|
||||
func (self *SHost) GetGlobalId() string {
|
||||
return self.GetAccessIp()
|
||||
}
|
||||
|
||||
func (self *SHost) GetStatus() string {
|
||||
/*
|
||||
HostSystemPowerStatePoweredOn = HostSystemPowerState("poweredOn")
|
||||
HostSystemPowerStatePoweredOff = HostSystemPowerState("poweredOff")
|
||||
HostSystemPowerStateStandBy = HostSystemPowerState("standBy")
|
||||
HostSystemPowerStateUnknown = HostSystemPowerState("unknown")
|
||||
*/
|
||||
switch self.getHostSystem().Summary.Runtime.PowerState {
|
||||
case types.HostSystemPowerStatePoweredOn:
|
||||
return models.HOST_STATUS_RUNNING
|
||||
case types.HostSystemPowerStatePoweredOff:
|
||||
return models.HOST_STATUS_READY
|
||||
default:
|
||||
return models.HOST_STATUS_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHost) Refresh() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SHost) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SHost) fetchVMs() error {
|
||||
if self.vms != nil {
|
||||
return nil
|
||||
}
|
||||
var vms []mo.VirtualMachine
|
||||
err := self.manager.references2Objects(self.getHostSystem().Vm, VIRTUAL_MACHINE_PROPS, &vms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dc, err := self.GetDatacenter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
self.vms = make([]cloudprovider.ICloudVM, len(vms))
|
||||
for i := 0; i < len(vms); i += 1 {
|
||||
self.vms[i] = NewVirtualMachine(self.manager, &vms[i], dc, self)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
|
||||
err := self.fetchVMs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.vms, nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
id = self.manager.getPrivateId(id)
|
||||
|
||||
vms, err := self.GetIVMs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(vms); i += 1 {
|
||||
if vms[i].GetGlobalId() == id {
|
||||
return vms[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SHost) GetEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostStatus() string {
|
||||
/*
|
||||
HostSystemConnectionStateConnected = HostSystemConnectionState("connected")
|
||||
HostSystemConnectionStateNotResponding = HostSystemConnectionState("notResponding")
|
||||
HostSystemConnectionStateDisconnected = HostSystemConnectionState("disconnected")
|
||||
*/
|
||||
switch self.getHostSystem().Summary.Runtime.ConnectionState {
|
||||
case types.HostSystemConnectionStateConnected:
|
||||
return models.HOST_ONLINE
|
||||
default:
|
||||
return models.HOST_OFFLINE
|
||||
}
|
||||
}
|
||||
|
||||
func findHostNicByMac(nicInfoList []SHostNicInfo, mac string) *SHostNicInfo {
|
||||
for i := 0; i < len(nicInfoList); i += 1 {
|
||||
if nicInfoList[i].Mac == mac {
|
||||
return &nicInfoList[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) getAdminNic() *SHostNicInfo {
|
||||
nics := self.getNicInfo()
|
||||
for i := 0; i < len(nics); i += 1 {
|
||||
if nics[i].NicType == models.NIC_TYPE_ADMIN {
|
||||
return &nics[i]
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(nics); i += 1 {
|
||||
if len(nics[i].IpAddr) > 0 {
|
||||
return &nics[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) getNicInfo() []SHostNicInfo {
|
||||
if self.nicInfo == nil {
|
||||
self.nicInfo = self.fetchNicInfo()
|
||||
}
|
||||
return self.nicInfo
|
||||
}
|
||||
|
||||
func (self *SHost) fetchNicInfo() []SHostNicInfo {
|
||||
moHost := self.getHostSystem()
|
||||
|
||||
nicInfoList := make([]SHostNicInfo, 0)
|
||||
|
||||
for i, nic := range moHost.Config.Network.Pnic {
|
||||
info := SHostNicInfo{}
|
||||
info.Dev = nic.Device
|
||||
info.Driver = nic.Driver
|
||||
info.Mac = netutils.FormatMacAddr(nic.Mac)
|
||||
info.Index = i
|
||||
info.LinkUp = false
|
||||
nicInfoList = append(nicInfoList, info)
|
||||
}
|
||||
|
||||
for _, nic := range moHost.Config.Network.Vnic {
|
||||
mac := netutils.FormatMacAddr(nic.Spec.Mac)
|
||||
pnic := findHostNicByMac(nicInfoList, mac)
|
||||
if pnic != nil {
|
||||
pnic.IpAddr = nic.Spec.Ip.IpAddress
|
||||
if nic.Spec.Portgroup == "Management Network" {
|
||||
pnic.NicType = models.NIC_TYPE_ADMIN
|
||||
}
|
||||
pnic.LinkUp = true
|
||||
}
|
||||
}
|
||||
|
||||
return nicInfoList
|
||||
}
|
||||
|
||||
func (self *SHost) GetAccessIp() string {
|
||||
adminNic := self.getAdminNic()
|
||||
if adminNic != nil {
|
||||
return adminNic.IpAddr
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetAccessMac() string {
|
||||
adminNic := self.getAdminNic()
|
||||
if adminNic != nil {
|
||||
return adminNic.Mac
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SSysInfo struct {
|
||||
Manufacture string
|
||||
Model string
|
||||
SerialNumber string
|
||||
}
|
||||
|
||||
func (self *SHost) GetSysInfo() jsonutils.JSONObject {
|
||||
sysinfo := SSysInfo{}
|
||||
sysinfo.Manufacture = self.getHostSystem().Summary.Hardware.Vendor
|
||||
sysinfo.Model = self.getHostSystem().Summary.Hardware.Model
|
||||
sysinfo.SerialNumber = self.getHostSystem().Hardware.SystemInfo.SerialNumber
|
||||
return jsonutils.Marshal(&sysinfo)
|
||||
}
|
||||
|
||||
func (self *SHost) GetSN() string {
|
||||
return self.getHostSystem().Hardware.SystemInfo.SerialNumber
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuCount() int8 {
|
||||
return int8(self.getHostSystem().Summary.Hardware.NumCpuThreads)
|
||||
}
|
||||
|
||||
func (self *SHost) GetNodeCount() int8 {
|
||||
return int8(self.getHostSystem().Summary.Hardware.NumCpuPkgs)
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuDesc() string {
|
||||
return self.getHostSystem().Summary.Hardware.CpuModel
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuMhz() int {
|
||||
return int(self.getHostSystem().Summary.Hardware.CpuMhz)
|
||||
}
|
||||
|
||||
func (self *SHost) GetMemSizeMB() int {
|
||||
return int(self.getHostSystem().Summary.Hardware.MemorySize / 1024 / 1024)
|
||||
}
|
||||
|
||||
/*func (self *SHost) fetchStorageInfo() {
|
||||
adapterList := make([]SHostStorageAdapterInfo, 0)
|
||||
driversTable := make(map[string]SHostStorageDriverInfo, 0)
|
||||
enclosuresTable := make(map[string]SHostStorageEnclosureInfo, 0)
|
||||
moHost := self.getHostSystem()
|
||||
|
||||
for i, ad := range moHost.Config.StorageDevice.HostBusAdapter {
|
||||
adinfo := ad.GetHostHostBusAdapter()
|
||||
if adinfo == nil {
|
||||
log.Errorf("Fail to GetHostHostBusAdapter")
|
||||
continue
|
||||
}
|
||||
info := SHostStorageAdapterInfo{}
|
||||
info.Device = adinfo.Device
|
||||
info.Model = adinfo.Model
|
||||
info.Driver = adinfo.Driver
|
||||
info.Pci = adinfo.Pci
|
||||
info.Drivers = make([]SHostStorageDriverInfo, 0)
|
||||
info.Enclosure = -1
|
||||
adapterList = append(adapterList, info)
|
||||
}
|
||||
|
||||
for i, drv := range moHost.Config.StorageDevice.ScsiLun {
|
||||
lunInfo := drv.GetScsiLun()
|
||||
if lunInfo == nil {
|
||||
log.Errorf("fail to GetScsiLun")
|
||||
continue
|
||||
}
|
||||
if lunInfo.DeviceType == "disk" {
|
||||
info := SHostStorageDriverInfo{}
|
||||
info.CN = lunInfo.CanonicalName
|
||||
info.Name = lunInfo.DisplayName
|
||||
info.Model = lunInfo.Model
|
||||
info.Vendor = lunInfo.Vendor
|
||||
info.Revision = lunInfo.Revision
|
||||
info.Status = lunInfo.OperationalState[0]
|
||||
// info.SSD = lunInfo.
|
||||
// info.Dev =
|
||||
// info.Size = lunInfo.S
|
||||
} else if lunInfo.DeviceType == "enclosure" {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func (self *SHost) GetStorageSizeMB() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetStorageType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostType() string {
|
||||
return models.HOST_TYPE_ESXI
|
||||
}
|
||||
|
||||
func (self *SHost) GetManagerId() string {
|
||||
return self.manager.providerId
|
||||
}
|
||||
|
||||
func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, vswitchId string, ipAddr string, desc string,
|
||||
passwd string, storageType string, diskSizes []int, publicKey string) (cloudprovider.ICloudVM, error) {
|
||||
log.Debugf("CreateVM")
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/view"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/vmware/govmomi/session"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
CLOUD_PROVIDER_VMWARE = models.CLOUD_PROVIDER_VMWARE
|
||||
)
|
||||
|
||||
type SESXiClient struct {
|
||||
providerId string
|
||||
providerName string
|
||||
host string
|
||||
port int
|
||||
account string
|
||||
password string
|
||||
client *govmomi.Client
|
||||
context context.Context
|
||||
|
||||
datacenters []*SDatacenter
|
||||
}
|
||||
|
||||
func NewESXiClient(providerId string, providerName string, host string, port int, account string, passwd string) (*SESXiClient, error) {
|
||||
cli := &SESXiClient{providerId: providerId, providerName: providerName,
|
||||
host: host, port: port, account: account, password: passwd, context: context.Background()}
|
||||
|
||||
err := cli.connect()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) url() string {
|
||||
if cli.port == 443 || cli.port == 0 {
|
||||
return fmt.Sprintf("https://%s/sdk", cli.host)
|
||||
} else {
|
||||
return fmt.Sprintf("https://%s:%d/sdk", cli.host, cli.port)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) connect() error {
|
||||
u, err := url.Parse(cli.url())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Illegal url %s: %s", cli.url(), err)
|
||||
}
|
||||
|
||||
govmcli, err := govmomi.NewClient(cli.context, u, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userinfo := url.UserPassword(cli.account, cli.password)
|
||||
|
||||
err = govmcli.Login(cli.context, userinfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli.client = govmcli
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) disconnect() error {
|
||||
if cli.client != nil {
|
||||
return cli.client.Logout(cli.context)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) About() jsonutils.JSONObject {
|
||||
return jsonutils.Marshal(&cli.client.ServiceContent.About)
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) GetUUID() string {
|
||||
about := cli.client.ServiceContent.About
|
||||
return about.InstanceUuid
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) fetchDatacenters() error {
|
||||
var dcs []mo.Datacenter
|
||||
err := cli.scanAllMObjects(DATACENTER_PROPS, &dcs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli.datacenters = make([]*SDatacenter, len(dcs))
|
||||
for i := 0; i < len(dcs); i += 1 {
|
||||
cli.datacenters[i] = newDatacenter(cli, &dcs[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) scanAllMObjects(props []string, dst interface{}) error {
|
||||
return cli.scanMObjects(cli.client.ServiceContent.RootFolder, props, dst)
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) scanMObjects(folder types.ManagedObjectReference, props []string, dst interface{}) error {
|
||||
dstValue := reflect.Indirect(reflect.ValueOf(dst))
|
||||
dstType := dstValue.Type()
|
||||
dstEleType := dstType.Elem()
|
||||
|
||||
resType := dstEleType.Name()
|
||||
m := view.NewManager(cli.client.Client)
|
||||
|
||||
v, err := m.CreateContainerView(cli.context, folder, []string{resType}, true)
|
||||
if err != nil {
|
||||
log.Fatalf("%s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
defer v.Destroy(cli.context)
|
||||
|
||||
err = v.Retrieve(cli.context, []string{resType}, props, dst)
|
||||
if err != nil {
|
||||
log.Fatalf("%s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func getStructFields(dst interface{}) []string {
|
||||
dataValue := reflect.Indirect(reflect.ValueOf(dst))
|
||||
dataType := dataValue.Type()
|
||||
if dataType.Kind() != reflect.Struct {
|
||||
log.Warningf("GetStructFeilds for non-struct data")
|
||||
return nil
|
||||
}
|
||||
return _getStructFields(dataType)
|
||||
}
|
||||
|
||||
func _getStructFields(dataType reflect.Type) []string {
|
||||
ret := make([]string, 0)
|
||||
for i := 1; i < dataType.NumField(); i += 1 {
|
||||
field := dataType.Field(i)
|
||||
if field.Type.Kind() == reflect.Struct && field.Anonymous {
|
||||
subfields := _getStructFields(field.Type)
|
||||
ret = append(ret, subfields...)
|
||||
} else if gotypes.IsFieldExportable(field.Name) {
|
||||
log.Debugf("%s: %s", field.Name, field.Type.Name())
|
||||
ret = append(ret, utils.CamelSplit(field.Name, "_"))
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
*/
|
||||
|
||||
func (cli *SESXiClient) references2Objects(refs []types.ManagedObjectReference, props []string, dst interface{}) error {
|
||||
pc := property.DefaultCollector(cli.client.Client)
|
||||
err := pc.Retrieve(cli.context, refs, []string{"name", "config", "summary"}, dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) reference2Object(ref types.ManagedObjectReference, props []string, dst interface{}) error {
|
||||
pc := property.DefaultCollector(cli.client.Client)
|
||||
return pc.RetrieveOne(cli.context, ref, props, dst)
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) GetDatacenters() ([]*SDatacenter, error) {
|
||||
if cli.datacenters == nil {
|
||||
err := cli.fetchDatacenters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return cli.datacenters, nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) FindDatacenterById(dcId string) (*SDatacenter, error) {
|
||||
dcs, err := cli.GetDatacenters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(dcs); i += 1 {
|
||||
if dcs[i].GetId() == dcId {
|
||||
return dcs[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) getPrivateId(idStr string) string {
|
||||
if strings.HasPrefix(idStr, cli.providerId) {
|
||||
idStr = idStr[len(cli.providerId)+1:]
|
||||
}
|
||||
return idStr
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) FindHostByIp(hostIp string) (*SHost, error) {
|
||||
searchIndex := object.NewSearchIndex(cli.client.Client)
|
||||
hostRef, err := searchIndex.FindByIp(cli.context, nil, cli.getPrivateId(hostIp), false)
|
||||
if err != nil {
|
||||
log.Errorf("searchIndex.FindByIp fail %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var host mo.HostSystem
|
||||
err = cli.reference2Object(hostRef.Reference(), HOST_SYSTEM_PROPS, &host)
|
||||
if err != nil {
|
||||
log.Errorf("reference2Object fail %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHost(cli, &host, nil), nil
|
||||
}
|
||||
|
||||
func (cli *SESXiClient) acquireCloneTicket() (string, error) {
|
||||
manager := session.NewManager(cli.client.Client)
|
||||
return manager.AcquireCloneTicket(cli.context)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package esxi
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
cli, err := NewESXiClient("", "", "10.168.222.104", 443, "root", "123@Vmware")
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
} else {
|
||||
t.Logf("%s", cli.About())
|
||||
|
||||
cli.fetchDatacenters()
|
||||
|
||||
host, err := cli.FindHostByIp("10.168.222.104")
|
||||
if err != nil {
|
||||
t.Errorf("find_host_by_ip %s", err)
|
||||
} else {
|
||||
t.Logf("host %s %s", host.GetAccessIp(), host.GetName())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type SManagedObject struct {
|
||||
manager *SESXiClient
|
||||
datacenter *SDatacenter
|
||||
object mo.Entity
|
||||
|
||||
path []string
|
||||
}
|
||||
|
||||
func newManagedObject(manager *SESXiClient, moobj mo.Entity, dc *SDatacenter) SManagedObject {
|
||||
return SManagedObject{manager: manager, object: moobj, datacenter: dc}
|
||||
}
|
||||
|
||||
func (self *SManagedObject) GetName() string {
|
||||
return self.object.Entity().Name
|
||||
}
|
||||
|
||||
func (self *SManagedObject) GetId() string {
|
||||
return self.object.Entity().Self.Value
|
||||
}
|
||||
|
||||
func (self *SManagedObject) GetType() string {
|
||||
return self.object.Entity().Self.Type
|
||||
}
|
||||
|
||||
func (self *SManagedObject) getCurrentParentEntity() *mo.ManagedEntity {
|
||||
return self.getParentEntity(self.object.Entity())
|
||||
}
|
||||
|
||||
func (self *SManagedObject) getParentEntity(obj *mo.ManagedEntity) *mo.ManagedEntity {
|
||||
parent := obj.Parent
|
||||
if parent != nil {
|
||||
var entity mo.ManagedEntity
|
||||
err := self.manager.reference2Object(*parent, []string{"name", "parent"}, &entity)
|
||||
if err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("getParentEntity %s %s %s", entity.Self.Type, entity.Self.Value, entity.Name)
|
||||
return &entity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reverseArray(array interface{}) {
|
||||
arrayValue := reflect.Indirect(reflect.ValueOf(array))
|
||||
if arrayValue.Kind() != reflect.Slice && arrayValue.Kind() != reflect.Array {
|
||||
log.Errorf("reverse non array or slice")
|
||||
return
|
||||
}
|
||||
tmp := reflect.Indirect(reflect.New(arrayValue.Type().Elem()))
|
||||
for i, j := 0, arrayValue.Len()-1; i < j; i, j = i+1, j-1 {
|
||||
tmpi := arrayValue.Index(i)
|
||||
tmpj := arrayValue.Index(j)
|
||||
tmp.Set(tmpi)
|
||||
tmpi.Set(tmpj)
|
||||
tmpj.Set(tmp)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SManagedObject) fetchPath() []string {
|
||||
path := make([]string, 0)
|
||||
obj := self.object.Entity()
|
||||
for obj != nil {
|
||||
path = append(path, obj.Name)
|
||||
obj = self.getParentEntity(obj)
|
||||
}
|
||||
reverseArray(path)
|
||||
return path
|
||||
}
|
||||
|
||||
func (self *SManagedObject) GetPath() []string {
|
||||
if self.path == nil {
|
||||
self.path = self.fetchPath()
|
||||
}
|
||||
return self.path
|
||||
}
|
||||
|
||||
func (self *SManagedObject) findInParents(objType string) *mo.ManagedEntity {
|
||||
obj := self.object.Entity()
|
||||
|
||||
for obj != nil && obj.Self.Type != objType {
|
||||
obj = self.getParentEntity(obj)
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
func (self *SManagedObject) fetchDatacenter() (*SDatacenter, error) {
|
||||
me := self.findInParents("Datacenter")
|
||||
if me == nil {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
return self.manager.FindDatacenterById(me.Self.Value)
|
||||
}
|
||||
|
||||
func (self *SManagedObject) GetDatacenter() (*SDatacenter, error) {
|
||||
if self.datacenter == nil {
|
||||
dc, err := self.fetchDatacenter()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
self.datacenter = dc
|
||||
}
|
||||
return self.datacenter, nil
|
||||
}
|
||||
|
||||
func (self *SManagedObject) GetDatacenterPath() []string {
|
||||
dc, err := self.GetDatacenter()
|
||||
if err != nil {
|
||||
log.Errorf("cannot find datacenter")
|
||||
return nil
|
||||
}
|
||||
path := dc.GetPath()
|
||||
return path[1:]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package esxi
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestReverseArray(t *testing.T) {
|
||||
a := []int{1, 2, 3, 4, 5}
|
||||
|
||||
reverseArray(a)
|
||||
t.Logf("%#v", a)
|
||||
|
||||
b := []string{"1", "2", "3", "4", "5"}
|
||||
reverseArray(b)
|
||||
t.Logf("%#v", b)
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/util/esxi"
|
||||
)
|
||||
|
||||
type SESXiProviderFactory struct {
|
||||
providerTable map[string]*SESXiProvider
|
||||
}
|
||||
|
||||
func (self *SESXiProviderFactory) GetId() string {
|
||||
return esxi.CLOUD_PROVIDER_VMWARE
|
||||
}
|
||||
|
||||
func parseHostPort(host string, defPort int) (string, int, error) {
|
||||
colonPos := strings.IndexByte(host, ':')
|
||||
if colonPos > 0 {
|
||||
h := host[:colonPos]
|
||||
p, err := strconv.Atoi(host[colonPos+1:])
|
||||
if err != nil {
|
||||
log.Errorf("Invalid host %s", host)
|
||||
return "", 0, err
|
||||
}
|
||||
if p == 0 {
|
||||
p = defPort
|
||||
}
|
||||
return h, p, nil
|
||||
} else {
|
||||
return host, defPort, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SESXiProviderFactory) GetProvider(providerId, providerName, urlStr, account, secret string) (cloudprovider.ICloudProvider, error) {
|
||||
provider, ok := self.providerTable[providerId]
|
||||
if ok {
|
||||
return provider, nil
|
||||
}
|
||||
parts, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
host, port, err := parseHostPort(parts.Host, 443)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := esxi.NewESXiClient(providerId, providerName, host, port, account, secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
self.providerTable[providerId] = &SESXiProvider{client: client}
|
||||
return self.providerTable[providerId], nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
factory := SESXiProviderFactory{
|
||||
providerTable: make(map[string]*SESXiProvider),
|
||||
}
|
||||
cloudprovider.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SESXiProvider struct {
|
||||
client *esxi.SESXiClient
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) IsPublicCloud() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetId() string {
|
||||
return esxi.CLOUD_PROVIDER_VMWARE
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetName() string {
|
||||
return esxi.CLOUD_PROVIDER_VMWARE
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetSysInfo() (jsonutils.JSONObject, error) {
|
||||
return self.client.About(), nil
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
host, err := self.client.FindHostByIp(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return host, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SESXiProvider) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/esxi"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type DatacenterListOptions struct {
|
||||
}
|
||||
shellutils.R(&DatacenterListOptions{}, "dc-list", "List all datacenters", func(cli *esxi.SESXiClient, args *DatacenterListOptions) error {
|
||||
dcs, err := cli.GetDatacenters()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(dcs, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/esxi"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type HostListOptions struct {
|
||||
DATACENTER string `help:"List hosts in datacenter"`
|
||||
}
|
||||
shellutils.R(&HostListOptions{}, "host-list", "List hosts in datacenter", func(cli *esxi.SESXiClient, args *HostListOptions) error {
|
||||
dc, err := cli.FindDatacenterById(args.DATACENTER)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hosts, err := dc.GetIHosts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(hosts, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type HostShowOptions struct {
|
||||
IP string `help:"Host IP"`
|
||||
}
|
||||
shellutils.R(&HostShowOptions{}, "host-show", "Show details of a host by IP", func(cli *esxi.SESXiClient, args *HostShowOptions) error {
|
||||
host, err := cli.FindHostByIp(args.IP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(host)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/esxi"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type DatastoreListOptions struct {
|
||||
DATACENTER string `help:"List datastores in datacenter"`
|
||||
}
|
||||
shellutils.R(&DatastoreListOptions{}, "ds-list", "List datastores in datacenter", func(cli *esxi.SESXiClient, args *DatastoreListOptions) error {
|
||||
dc, err := cli.FindDatacenterById(args.DATACENTER)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ds, err := dc.GetIStorages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(ds, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package shell
|
||||
|
||||
import "github.com/yunionio/onecloud/pkg/util/printutils"
|
||||
|
||||
func printList(data interface{}, columns []string) {
|
||||
printutils.PrintGetterList(data, columns)
|
||||
}
|
||||
|
||||
func printObject(obj interface{}) {
|
||||
printutils.PrintGetterObject(obj)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/util/esxi"
|
||||
"github.com/yunionio/onecloud/pkg/util/printutils"
|
||||
"github.com/yunionio/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type VirtualMachineListOptions struct {
|
||||
HOSTIP string `help:"Host IP"`
|
||||
}
|
||||
shellutils.R(&VirtualMachineListOptions{}, "vm-list", "List vms of a host", func(cli *esxi.SESXiClient, args *VirtualMachineListOptions) error {
|
||||
host, err := cli.FindHostByIp(args.HOSTIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vms, err := host.GetIVMs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(vms, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
type VirtualMachineShowOptions struct {
|
||||
HOSTIP string `help:"Host IP"`
|
||||
VMID string `help:"VM ID"`
|
||||
}
|
||||
shellutils.R(&VirtualMachineShowOptions{}, "vm-show", "Show vm details", func(cli *esxi.SESXiClient, args *VirtualMachineShowOptions) error {
|
||||
host, err := cli.FindHostByIp(args.HOSTIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vm, err := host.GetIVMById(args.VMID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(vm)
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&VirtualMachineShowOptions{}, "vm-vnc", "Show vm VNC details", func(cli *esxi.SESXiClient, args *VirtualMachineShowOptions) error {
|
||||
host, err := cli.FindHostByIp(args.HOSTIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vm, err := host.GetIVMById(args.VMID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := vm.GetVNCInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printutils.PrintJSONObject(info)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
var DATASTORE_PROPS = []string{"name", "parent"}
|
||||
|
||||
type SDatastore struct {
|
||||
SManagedObject
|
||||
}
|
||||
|
||||
func NewDatastore(manager *SESXiClient, ds *mo.Datastore, dc *SDatacenter) *SDatastore {
|
||||
return &SDatastore{SManagedObject: newManagedObject(manager, ds, dc)}
|
||||
}
|
||||
|
||||
func (self *SDatastore) getDatastore() *mo.Datastore {
|
||||
return self.object.(*mo.Datastore)
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetGlobalId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetStatus() string {
|
||||
if self.getDatastore().Summary.Accessible {
|
||||
return models.STORAGE_ONLINE
|
||||
} else {
|
||||
return models.STORAGE_OFFLINE
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDatastore) Refresh() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDatastore) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDatastore) getVolumeId() string {
|
||||
return self.getDatastore().Summary.Type
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetIStoragecache() cloudprovider.ICloudStoragecache {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetIZone() cloudprovider.ICloudZone {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetStorageType() string {
|
||||
return self.getDatastore().Summary.Type
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetMediumType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetCapacityMB() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetStorageConf() jsonutils.JSONObject {
|
||||
conf := jsonutils.NewDict()
|
||||
return conf
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetManagerId() string {
|
||||
return self.manager.providerId
|
||||
}
|
||||
|
||||
func (self *SDatastore) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
|
||||
"fmt"
|
||||
"github.com/vmware/govmomi/object"
|
||||
)
|
||||
|
||||
var VIRTUAL_MACHINE_PROPS = []string{"name", "parent", "runtime", "summary"}
|
||||
|
||||
type SVirtualMachine struct {
|
||||
SManagedObject
|
||||
|
||||
host *SHost
|
||||
}
|
||||
|
||||
func NewVirtualMachine(manager *SESXiClient, vm *mo.VirtualMachine, dc *SDatacenter, host *SHost) *SVirtualMachine {
|
||||
return &SVirtualMachine{SManagedObject: newManagedObject(manager, vm, dc), host: host}
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) getVirtualMachine() *mo.VirtualMachine {
|
||||
return self.object.(*mo.VirtualMachine)
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetGlobalId() string {
|
||||
return self.getUuid()
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetStatus() string {
|
||||
vm := object.NewVirtualMachine(self.manager.client.Client, self.getVirtualMachine().Self)
|
||||
state, err := vm.PowerState(self.manager.context)
|
||||
if err != nil {
|
||||
return models.VM_UNKNOWN
|
||||
}
|
||||
switch state {
|
||||
case types.VirtualMachinePowerStatePoweredOff:
|
||||
return models.VM_READY
|
||||
case types.VirtualMachinePowerStatePoweredOn:
|
||||
return models.VM_RUNNING
|
||||
case types.VirtualMachinePowerStateSuspended:
|
||||
return models.VM_SUSPEND
|
||||
default:
|
||||
return models.VM_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) Refresh() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) getUuid() string {
|
||||
return self.getVirtualMachine().Summary.Config.Uuid
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetCreateTime() time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetIHost() cloudprovider.ICloudHost {
|
||||
return self.host
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetINics() ([]cloudprovider.ICloudNic, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetEIP() cloudprovider.ICloudEIP {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetVcpuCount() int8 {
|
||||
// ret = self.obj.summary.config.numCpu
|
||||
return int8(self.getVirtualMachine().Summary.Config.NumCpu)
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetVmemSizeMB() int {
|
||||
// self.obj.summary.config.memorySizeMB
|
||||
return int(self.getVirtualMachine().Summary.Config.MemorySizeMB)
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetBootOrder() string {
|
||||
return "cdn"
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetVga() string {
|
||||
return "vga"
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetVdi() string {
|
||||
return "vmrc"
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetOSType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetOSName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetBios() string {
|
||||
// self.obj.config.firmware
|
||||
switch self.getVirtualMachine().Config.Firmware {
|
||||
case "efi":
|
||||
return "UEFI"
|
||||
case "bios":
|
||||
return "BIOS"
|
||||
default:
|
||||
return "BIOS"
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetMachine() string {
|
||||
return "pc"
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetHypervisor() string {
|
||||
return models.HYPERVISOR_ESXI
|
||||
}
|
||||
|
||||
// GetSecurityGroup() ICloudSecurityGroup
|
||||
|
||||
func (self *SVirtualMachine) StartVM() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) StopVM(isForce bool) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) DeleteVM() error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetVNCInfo() (jsonutils.JSONObject, error) {
|
||||
info, err := self.acquireWebmksTicket("webmks")
|
||||
if err != nil {
|
||||
info, err = self.acquireVmrcUrl()
|
||||
}
|
||||
return info, err
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) acquireWebmksTicket(ticketType string) (jsonutils.JSONObject, error) {
|
||||
vm := object.NewVirtualMachine(self.manager.client.Client, self.getVirtualMachine().Self)
|
||||
ticket, err := vm.AcquireTicket(self.manager.context, ticketType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := jsonutils.NewDict()
|
||||
|
||||
host := ticket.Host
|
||||
if len(host) == 0 {
|
||||
host = self.manager.host
|
||||
}
|
||||
port := ticket.Port
|
||||
if port == 0 {
|
||||
port = int32(self.manager.port)
|
||||
}
|
||||
if port == 0 {
|
||||
port = 443
|
||||
}
|
||||
/*
|
||||
ret.Add(jsonutils.NewString(ticketType), "type")
|
||||
ret.Add(jsonutils.NewString(ticket.Host), "host")
|
||||
ret.Add(jsonutils.NewInt(int64(ticket.Port)), "port")
|
||||
ret.Add(jsonutils.NewString(ticket.Ticket), "ticket")
|
||||
ret.Add(jsonutils.NewString(ticket.SslThumbprint), "slThumbprint")
|
||||
ret.Add(jsonutils.NewString(ticket.CfgFile), "cfgFile")
|
||||
*/
|
||||
url := fmt.Sprintf("wss://%s:%d/ticket/%s", host, port, ticket.Ticket)
|
||||
ret.Add(jsonutils.NewString("wmks"), "protocol")
|
||||
ret.Add(jsonutils.NewString(url), "url")
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) acquireVmrcUrl() (jsonutils.JSONObject, error) {
|
||||
ticket, err := self.manager.acquireCloneTicket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := jsonutils.NewDict()
|
||||
ret.Add(jsonutils.NewString("vmrc"), "protocol")
|
||||
port := self.manager.port
|
||||
if port == 0 {
|
||||
port = 443
|
||||
}
|
||||
url := fmt.Sprintf("vmrc://clone:%s@%s:%d/?moid=%s", ticket, self.manager.host, port, self.GetId())
|
||||
ret.Add(jsonutils.NewString(url), "url")
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package printutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
func getter2json(obj interface{}) jsonutils.JSONObject {
|
||||
jsonDict := jsonutils.NewDict()
|
||||
|
||||
objValue := reflect.ValueOf(obj)
|
||||
objType := reflect.TypeOf(obj)
|
||||
|
||||
// log.Debugf("getter2json %d", objValue.NumMethod())
|
||||
|
||||
for i := 0; i < objValue.NumMethod(); i += 1 {
|
||||
methodValue := objValue.Method(i)
|
||||
method := objType.Method(i)
|
||||
methodName := method.Name
|
||||
methodType := methodValue.Type()
|
||||
|
||||
if strings.HasPrefix(methodName, "Get") && methodType.NumIn() == 0 && methodType.NumOut() == 1 {
|
||||
fieldName := utils.CamelSplit(methodName[3:], "_")
|
||||
out := methodValue.Call([]reflect.Value{})
|
||||
if len(out) == 1 {
|
||||
jsonDict.Add(jsonutils.Marshal(out[0].Interface()), fieldName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return jsonDict
|
||||
}
|
||||
|
||||
func PrintGetterList(data interface{}, columns []string) {
|
||||
dataValue := reflect.ValueOf(data)
|
||||
if dataValue.Kind() != reflect.Slice {
|
||||
fmt.Println("Invalid list data")
|
||||
return
|
||||
}
|
||||
jsonList := make([]jsonutils.JSONObject, dataValue.Len())
|
||||
for i := 0; i < dataValue.Len(); i += 1 {
|
||||
jsonList[i] = getter2json(dataValue.Index(i).Interface())
|
||||
}
|
||||
list := &modules.ListResult{
|
||||
Data: jsonList,
|
||||
Total: dataValue.Len(),
|
||||
Limit: 0,
|
||||
Offset: 0,
|
||||
}
|
||||
PrintJSONList(list, columns)
|
||||
}
|
||||
|
||||
func PrintGetterObject(obj interface{}) {
|
||||
PrintJSONObject(getter2json(obj))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package printjson
|
||||
package printutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
func PrintList(list *modules.ListResult, columns []string) {
|
||||
func PrintJSONList(list *modules.ListResult, columns []string) {
|
||||
colsWithData := make([]string, 0)
|
||||
if columns == nil || len(columns) == 0 {
|
||||
colsWithDataMap := make(map[string]bool)
|
||||
@@ -75,7 +75,7 @@ func PrintList(list *modules.ListResult, columns []string) {
|
||||
fmt.Println("*** ", title, " ***")
|
||||
}
|
||||
|
||||
func PrintObject(obj jsonutils.JSONObject) {
|
||||
func PrintJSONObject(obj jsonutils.JSONObject) {
|
||||
dict, ok := obj.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
fmt.Println("Not a valid JSON object:", obj.String())
|
||||
@@ -98,7 +98,7 @@ func PrintObject(obj jsonutils.JSONObject) {
|
||||
fmt.Println(pt.GetString(rows))
|
||||
}
|
||||
|
||||
func PrintBatchResults(results []modules.SubmitResult, columns []string) {
|
||||
func PrintJSONBatchResults(results []modules.SubmitResult, columns []string) {
|
||||
objs := make([]jsonutils.JSONObject, 0)
|
||||
errs := make([]jsonutils.JSONObject, 0)
|
||||
for _, r := range results {
|
||||
@@ -113,9 +113,9 @@ func PrintBatchResults(results []modules.SubmitResult, columns []string) {
|
||||
}
|
||||
}
|
||||
if len(objs) > 0 {
|
||||
PrintList(&modules.ListResult{Data: objs}, columns)
|
||||
PrintJSONList(&modules.ListResult{Data: objs}, columns)
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
PrintList(&modules.ListResult{Data: errs}, []string{"status", "id", "error"})
|
||||
PrintJSONList(&modules.ListResult{Data: errs}, []string{"status", "id", "error"})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package shell
|
||||
package printutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,10 +7,9 @@ import (
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/mcclient/modules"
|
||||
"github.com/yunionio/onecloud/pkg/util/printjson"
|
||||
)
|
||||
|
||||
func printList(data interface{}, total, offset, limit int, columns []string) {
|
||||
func PrintInterfaceList(data interface{}, total, offset, limit int, columns []string) {
|
||||
dataValue := reflect.ValueOf(data)
|
||||
if dataValue.Kind() != reflect.Slice {
|
||||
fmt.Println("Invalid list data")
|
||||
@@ -29,9 +28,9 @@ func printList(data interface{}, total, offset, limit int, columns []string) {
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
}
|
||||
printjson.PrintList(list, columns)
|
||||
PrintJSONList(list, columns)
|
||||
}
|
||||
|
||||
func printObject(obj interface{}) {
|
||||
printjson.PrintObject(jsonutils.Marshal(obj))
|
||||
func PrintInterfaceObject(obj interface{}) {
|
||||
PrintJSONObject(jsonutils.Marshal(obj))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package shell
|
||||
package shellutils
|
||||
|
||||
type CMD struct {
|
||||
Options interface{}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
secrets.yml
|
||||
dist/
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
---
|
||||
project_name: govc
|
||||
builds:
|
||||
- goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
- freebsd
|
||||
goarch:
|
||||
- amd64
|
||||
- 386
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
main: ./govc/main.go
|
||||
binary: govc
|
||||
flags: -compiler gc
|
||||
ldflags: -X github.com/vmware/govmomi/govc/flags.GitVersion={{.Version}}
|
||||
archive:
|
||||
name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}'
|
||||
format: tar.gz
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
files:
|
||||
- none*
|
||||
checksum:
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_checksums.txt'
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
- Merge pull request
|
||||
- Merge branch
|
||||
brew:
|
||||
github:
|
||||
owner: govmomi
|
||||
name: homebrew-tap
|
||||
commit_author:
|
||||
name: Alfred the Narwhal
|
||||
email: cna-alfred@vmware.com
|
||||
folder: Formula
|
||||
homepage: "https://github.com/vmware/govmomi/blob/master/govc/README.md"
|
||||
description: "govc is a vSphere CLI built on top of govmomi."
|
||||
test: |
|
||||
system "#{bin}/govc version"
|
||||
dockers:
|
||||
- image: vmware/govc
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
binary: govc
|
||||
tag_templates:
|
||||
- "{{ .Tag }}"
|
||||
- "v{{ .Major }}"
|
||||
- "v{{ .Major }}.{{ .Minor }}"
|
||||
- latest
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
Amit Bathla <abathla@.vmware.com> <abathla@promb-1s-dhcp216.eng.vmware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bdowns@vmware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@jivesoftware.com>
|
||||
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
|
||||
Cédric Blomart <cblomart@gmail.com> <cedric.blomart@minfin.fed.be>
|
||||
Cédric Blomart <cblomart@gmail.com> cedric <cblomart@gmail.com>
|
||||
David Stark <dave@davidstark.name> <david.stark@bskyb.com>
|
||||
Eric Gray <egray@vmware.com> <ericgray@users.noreply.github.com>
|
||||
Eric Yutao <eric.yutao@gmail.com> eric <eric.yutao@gmail.com>
|
||||
Fabio Rapposelli <fabio@vmware.com> <fabio@rapposelli.org>
|
||||
Henrik Hodne <henrik@travis-ci.com> <henrik@hodne.io>
|
||||
Jeremy Canady <jcanady@jackhenry.com> <jcanady@gmail.com>
|
||||
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com> takaaki.furukawa <takaaki.furukawa@mail.rakuten.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com> tkak <takaaki.frkw@gmail.com>
|
||||
Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> <anfernee.gui@gmail.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> Yongkun Anfernee Gui <agui@vmware.com>
|
||||
Zach Tucker <ztucker@vmware.com> <jzt@users.noreply.github.com>
|
||||
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
sudo: required
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- '1.10'
|
||||
go_import_path: github.com/vmware/govmomi
|
||||
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y xmlstarlet
|
||||
- make vendor
|
||||
|
||||
script:
|
||||
- make check test
|
||||
- GOOS=windows make install
|
||||
|
||||
after_success:
|
||||
- test -n "$TRAVIS_TAG" && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: curl -sL http://git.io/goreleaser | bash
|
||||
on:
|
||||
tags: true
|
||||
condition: $TRAVIS_OS_NAME = linux
|
||||
go: '1.10'
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
# changelog
|
||||
|
||||
### unreleased
|
||||
|
||||
* SetRootCAs on the soap.Client returns an error for invalid certificates
|
||||
|
||||
* Add ClusterComputeResource.MoveInto method
|
||||
|
||||
### 0.18.0 (2018-05-24)
|
||||
|
||||
* Add VirtualDiskManager wrapper to set UUID
|
||||
|
||||
* Add vmxnet2, pcnet32 and sriov to VirtualDeviceList.EthernetCardTypes
|
||||
|
||||
* Add new vSphere 6.7 APIs
|
||||
|
||||
* Decrease LoginExtensionByCertificate tunnel usage
|
||||
|
||||
* SAML token authentication support via SessionManager.LoginByToken
|
||||
|
||||
* New SSO admin client for managing users
|
||||
|
||||
* New STS client for issuing and renewing SAML tokens
|
||||
|
||||
* New Lookup Service client for discovering endpoints such as STS and ssoadmin
|
||||
|
||||
* Switch from gvt to go dep for managing dependencies
|
||||
|
||||
### 0.17.1 (2018-03-19)
|
||||
|
||||
* vcsim: add Destroy method for Folder and Datacenter types
|
||||
|
||||
* In progress.Reader emit final report on EOF.
|
||||
|
||||
* vcsim: add EventManager.QueryEvents
|
||||
|
||||
### 0.17.0 (2018-02-28)
|
||||
|
||||
* Add HostStorageSystem.AttachScsiLun method
|
||||
|
||||
* Avoid possible panic in Datastore.Stat (#969)
|
||||
|
||||
* Destroy event history collectors (#962)
|
||||
|
||||
* Add VirtualDiskManager.CreateChildDisk method
|
||||
|
||||
### 0.16.0 (2017-11-08)
|
||||
|
||||
* Add support for SOAP request operation ID header
|
||||
|
||||
* Moved ovf helpers from govc import.ovf command to ovf and nfc packages
|
||||
|
||||
* Added guest/toolbox (client) package
|
||||
|
||||
* Added toolbox package and toolbox command
|
||||
|
||||
* Added simulator package and vcsim command
|
||||
|
||||
### 0.15.0 (2017-06-19)
|
||||
|
||||
* WaitOptions.MaxWaitSeconds is now optional
|
||||
|
||||
* Support removal of ExtraConfig entries
|
||||
|
||||
* GuestPosixFileAttributes OwnerId and GroupId fields are now pointers,
|
||||
rather than omitempty ints to allow chown with root uid:gid
|
||||
|
||||
* Updated examples/ using view package
|
||||
|
||||
* Add DatastoreFile.TailFunc method
|
||||
|
||||
* Export VirtualMachine.FindSnapshot method
|
||||
|
||||
* Add AuthorizationManager {Enable,Disable}Methods
|
||||
|
||||
* Add PBM client
|
||||
|
||||
### 0.14.0 (2017-04-08)
|
||||
|
||||
* Add view.ContainerView type and methods
|
||||
|
||||
* Add Collector.RetrieveWithFilter method
|
||||
|
||||
* Add property.Filter type
|
||||
|
||||
* Implement EthernetCardBackingInfo for OpaqueNetwork
|
||||
|
||||
* Finder: support changing object root in find mode
|
||||
|
||||
* Add VirtualDiskManager.QueryVirtualDiskInfo
|
||||
|
||||
* Add performance.Manager APIs
|
||||
|
||||
### 0.13.0 (2017-03-02)
|
||||
|
||||
* Add DatastoreFileManager API wrapper
|
||||
|
||||
* Add HostVsanInternalSystem API wrappers
|
||||
|
||||
* Add Container support to view package
|
||||
|
||||
* Finder supports Folder recursion without specifying a path
|
||||
|
||||
* Add VirtualMachine.QueryConfigTarget method
|
||||
|
||||
* Add device option to VirtualMachine.WaitForNetIP
|
||||
|
||||
* Remove _Task suffix from vapp methods
|
||||
|
||||
### 0.12.1 (2016-12-19)
|
||||
|
||||
* Add DiagnosticLog helper
|
||||
|
||||
* Add DatastorePath helper
|
||||
|
||||
### 0.12.0 (2016-12-01)
|
||||
|
||||
* Disable use of service ticket for datastore HTTP access by default
|
||||
|
||||
* Attach context to HTTP requests for cancellations
|
||||
|
||||
* Update to vim25/6.5 API
|
||||
|
||||
### 0.11.4 (2016-11-15)
|
||||
|
||||
* Add object.AuthorizationManager methods: RetrieveRolePermissions, RetrieveAllPermissions, AddRole, RemoveRole, UpdateRole
|
||||
|
||||
### 0.11.3 (2016-11-08)
|
||||
|
||||
* Allow DatastoreFile.Follow reader to drain current body after stopping
|
||||
|
||||
### 0.11.2 (2016-11-01)
|
||||
|
||||
* Avoid possible NPE in VirtualMachine.Device method
|
||||
|
||||
* Add support for OpaqueNetwork type to Finder
|
||||
|
||||
* Add HostConfigManager.AccountManager support for ESX 5.5
|
||||
|
||||
### 0.11.1 (2016-10-27)
|
||||
|
||||
* Add Finder.ResourcePoolListAll method
|
||||
|
||||
### 0.11.0 (2016-10-25)
|
||||
|
||||
* Add object.DistributedVirtualPortgroup.Reconfigure method
|
||||
|
||||
### 0.10.0 (2016-10-20)
|
||||
|
||||
* Add option to set soap.Client.UserAgent
|
||||
|
||||
* Add service ticket thumbprint validation
|
||||
|
||||
* Update use of http.DefaultTransport fields to 1.7
|
||||
|
||||
* Set default locale to en_US (override with GOVMOMI_LOCALE env var)
|
||||
|
||||
* Add object.HostCertificateInfo (types.HostCertificateManagerCertificateInfo helpers)
|
||||
|
||||
* Add object.HostCertificateManager type and HostConfigManager.CertificateManager method
|
||||
|
||||
* Add soap.Client SetRootCAs and SetDialTLS methods
|
||||
|
||||
### 0.9.0 (2016-09-09)
|
||||
|
||||
* Add object.DatastoreFile helpers for streaming and tailing datastore files
|
||||
|
||||
* Add object VirtualMachine.Unregister method
|
||||
|
||||
* Add object.ListView methods: Add, Remove, Reset
|
||||
|
||||
* Update to Go 1.7 - using stdlib's context package
|
||||
|
||||
### 0.8.0 (2016-06-30)
|
||||
|
||||
* Add session.Manager.AcquireLocalTicket
|
||||
|
||||
* Include StoragePod in Finder.FolderList
|
||||
|
||||
* Add Finder methods for finding by ManagedObjectReference: Element, ObjectReference
|
||||
|
||||
* Add mo.ManagedObjectReference methods: Reference, String, FromString
|
||||
|
||||
* Add support using SessionManagerGenericServiceTicket.HostName for Datastore HTTP access
|
||||
|
||||
### 0.7.1 (2016-06-03)
|
||||
|
||||
* Fix object.ObjectName method
|
||||
|
||||
### 0.7.0 (2016-06-02)
|
||||
|
||||
* Move InventoryPath field to object.Common
|
||||
|
||||
* Add HostDatastoreSystem.CreateLocalDatastore method
|
||||
|
||||
* Add DatastoreNamespaceManager methods: CreateDirectory, DeleteDirectory
|
||||
|
||||
* Add HostServiceSystem
|
||||
|
||||
* Add HostStorageSystem methods: MarkAsSdd, MarkAsNonSdd, MarkAsLocal, MarkAsNonLocal
|
||||
|
||||
* Add HostStorageSystem.RescanAllHba method
|
||||
|
||||
### 0.6.2 (2016-05-11)
|
||||
|
||||
* Get complete file details in Datastore.Stat
|
||||
|
||||
* SOAP decoding fixes
|
||||
|
||||
* Add VirtualMachine.RemoveAllSnapshot
|
||||
|
||||
### 0.6.1 (2016-04-30)
|
||||
|
||||
* Fix mo.Entity interface
|
||||
|
||||
### 0.6.0 (2016-04-29)
|
||||
|
||||
* Add Common.Rename method
|
||||
|
||||
* Add mo.Entity interface
|
||||
|
||||
* Add OptionManager
|
||||
|
||||
* Add Finder.FolderList method
|
||||
|
||||
* Add VirtualMachine.WaitForNetIP method
|
||||
|
||||
* Add VirtualMachine.RevertToSnapshot method
|
||||
|
||||
* Add Datastore.Download method
|
||||
|
||||
### 0.5.0 (2016-03-30)
|
||||
|
||||
Generated fields using xsd type 'int' change to Go type 'int32'
|
||||
|
||||
VirtualDevice.UnitNumber field changed to pointer type
|
||||
|
||||
### 0.4.0 (2016-02-26)
|
||||
|
||||
* Add method to convert virtual device list to array with virtual device
|
||||
changes that can be used in the VirtualMachineConfigSpec.
|
||||
|
||||
* Make datastore cluster traversable in lister
|
||||
|
||||
* Add finder.DatastoreCluster methods (also known as storage pods)
|
||||
|
||||
* Add Drone CI check
|
||||
|
||||
* Add object.Datastore Type and AttachedClusterHosts methods
|
||||
|
||||
* Add finder.*OrDefault methods
|
||||
|
||||
### 0.3.0 (2016-01-16)
|
||||
|
||||
* Add object.VirtualNicManager wrapper
|
||||
|
||||
* Add object.HostVsanSystem wrapper
|
||||
|
||||
* Add object.HostSystem methods: EnterMaintenanceMode, ExitMaintenanceMode, Disconnect, Reconnect
|
||||
|
||||
* Add finder.Folder method
|
||||
|
||||
* Add object.Common.Destroy method
|
||||
|
||||
* Add object.ComputeResource.Reconfigure method
|
||||
|
||||
* Add license.AssignmentManager wrapper
|
||||
|
||||
* Add object.HostFirewallSystem wrapper
|
||||
|
||||
* Add object.DiagnosticManager wrapper
|
||||
|
||||
* Add LoginExtensionByCertificate support
|
||||
|
||||
* Add object.ExtensionManager
|
||||
|
||||
...
|
||||
|
||||
### 0.2.0 (2015-09-15)
|
||||
|
||||
* Update to vim25/6.0 API
|
||||
|
||||
* Stop returning children from `ManagedObjectList`
|
||||
|
||||
Change the `ManagedObjectList` function in the `find` package to only
|
||||
return the managed objects specified by the path argument and not their
|
||||
children. The original behavior was used by govc's `ls` command and is
|
||||
now available in the newly added function `ManagedObjectListChildren`.
|
||||
|
||||
* Add retry functionality to vim25 package
|
||||
|
||||
* Change finder functions to no longer take varargs
|
||||
|
||||
The `find` package had functions to return a list of objects, given a
|
||||
variable number of patterns. This makes it impossible to distinguish which
|
||||
patterns produced results and which ones didn't.
|
||||
|
||||
In particular for govc, where multiple arguments can be passed from the
|
||||
command line, it is useful to let the user know which ones produce results
|
||||
and which ones don't.
|
||||
|
||||
To evaluate multiple patterns, the user should call the find functions
|
||||
multiple times (either serially or in parallel).
|
||||
|
||||
* Make optional boolean fields pointers (`vim25/types`).
|
||||
|
||||
False is the zero value of a boolean field, which means they are not serialized
|
||||
if the field is marked "omitempty". If the field is a pointer instead, the zero
|
||||
value will be the nil pointer, and both true and false values are serialized.
|
||||
|
||||
### 0.1.0 (2015-03-17)
|
||||
|
||||
Prior to this version the API of this library was in flux.
|
||||
|
||||
Notable changes w.r.t. the state of this library before March 2015 are:
|
||||
|
||||
* All functions that may execute a request take a `context.Context` parameter.
|
||||
* The `vim25` package contains a minimal client implementation.
|
||||
* The property collector and its convenience functions live in the `property` package.
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
# Contributing to govmomi
|
||||
|
||||
## Getting started
|
||||
|
||||
First, fork the repository on GitHub to your personal account.
|
||||
|
||||
Note that _GOPATH_ can be any directory, the example below uses _$HOME/govmomi_.
|
||||
Change _$USER_ below to your github username if they are not the same.
|
||||
|
||||
``` shell
|
||||
export GOPATH=$HOME/govmomi
|
||||
go get github.com/vmware/govmomi
|
||||
cd $GOPATH/src/github.com/vmware/govmomi
|
||||
git config push.default nothing # anything to avoid pushing to vmware/govmomi by default
|
||||
git remote rename origin vmware
|
||||
git remote add $USER git@github.com:$USER/govmomi.git
|
||||
git fetch $USER
|
||||
```
|
||||
|
||||
## Installing from source
|
||||
|
||||
Compile the govmomi libraries and install govc using:
|
||||
|
||||
``` shell
|
||||
go install -v github.com/vmware/govmomi/govc
|
||||
```
|
||||
|
||||
Note that **govc/build.sh** is only used for building release binaries.
|
||||
|
||||
## Contribution flow
|
||||
|
||||
This is a rough outline of what a contributor's workflow looks like:
|
||||
|
||||
- Create a topic branch from where you want to base your work.
|
||||
- Make commits of logical units.
|
||||
- Make sure your commit messages are in the proper format (see below).
|
||||
- Update CHANGELOG.md and/or govc/CHANGELOG.md when appropriate.
|
||||
- Push your changes to a topic branch in your fork of the repository.
|
||||
- Submit a pull request to vmware/govmomi.
|
||||
|
||||
Example:
|
||||
|
||||
``` shell
|
||||
git checkout -b my-new-feature vmware/master
|
||||
git commit -a
|
||||
git push $USER my-new-feature
|
||||
```
|
||||
|
||||
### Stay in sync with upstream
|
||||
|
||||
When your branch gets out of sync with the vmware/master branch, use the following to update:
|
||||
|
||||
``` shell
|
||||
git checkout my-new-feature
|
||||
git fetch -a
|
||||
git rebase vmware/master
|
||||
git push --force-with-lease $USER my-new-feature
|
||||
```
|
||||
|
||||
### Updating pull requests
|
||||
|
||||
If your PR fails to pass CI or needs changes based on code review, you'll most likely want to squash these changes into
|
||||
existing commits.
|
||||
|
||||
If your pull request contains a single commit or your changes are related to the most recent commit, you can simply
|
||||
amend the commit.
|
||||
|
||||
``` shell
|
||||
git add .
|
||||
git commit --amend
|
||||
git push --force-with-lease $USER my-new-feature
|
||||
```
|
||||
|
||||
If you need to squash changes into an earlier commit, you can use:
|
||||
|
||||
``` shell
|
||||
git add .
|
||||
git commit --fixup <commit>
|
||||
git rebase -i --autosquash vmware/master
|
||||
git push --force-with-lease $USER my-new-feature
|
||||
```
|
||||
|
||||
Be sure to add a comment to the PR indicating your new changes are ready to review, as github does not generate a
|
||||
notification when you git push.
|
||||
|
||||
### Code style
|
||||
|
||||
The coding style suggested by the Golang community is used in govmomi. See the
|
||||
[style doc](https://github.com/golang/go/wiki/CodeReviewComments) for details.
|
||||
|
||||
Try to limit column width to 120 characters for both code and markdown documents such as this one.
|
||||
|
||||
### Format of the Commit Message
|
||||
|
||||
We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/).
|
||||
|
||||
Be sure to include any related GitHub issue references in the commit message.
|
||||
|
||||
## Reporting Bugs and Creating Issues
|
||||
|
||||
When opening a new issue, try to roughly follow the commit message format conventions above.
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# People who can (and typically have) contributed to this repository.
|
||||
#
|
||||
# This script is generated by contributors.sh
|
||||
#
|
||||
|
||||
Abhijeet Kasurde <akasurde@redhat.com>
|
||||
abrarshivani <abrarshivani@users.noreply.github.com>
|
||||
Adam Shannon <adamkshannon@gmail.com>
|
||||
akutz <sakutz@gmail.com>
|
||||
Alessandro Cortiana <alessandro.cortiana@gmail.com>
|
||||
Alex Bozhenko <alexbozhenko@fb.com>
|
||||
Alvaro Miranda <kikitux@gmail.com>
|
||||
amandahla <amanda.andrade@serpro.gov.br>
|
||||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br>
|
||||
Amit Bathla <abathla@.vmware.com>
|
||||
amit bezalel <amit.bezalel@hpe.com>
|
||||
Andrew Chin <andrew@andrewtchin.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com>
|
||||
aniketGslab <aniket.shinde@gslab.com>
|
||||
Arran Walker <arran.walker@zopa.com>
|
||||
Aryeh Weinreb <aryehweinreb@gmail.com>
|
||||
Austin Parker <aparker@apprenda.com>
|
||||
Balu Dontu <bdontu@vmware.com>
|
||||
bastienbc <bastien.barbe.creuly@gmail.com>
|
||||
Bob Killen <killen.bob@gmail.com>
|
||||
Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Bruce Downs <bruceadowns@gmail.com>
|
||||
Cédric Blomart <cblomart@gmail.com>
|
||||
Chris Marchesi <chrism@vancluevertech.com>
|
||||
Christian Höltje <docwhat@gerf.org>
|
||||
Clint Greenwood <cgreenwood@vmware.com>
|
||||
Danny Lockard <danny.lockard@banno.com>
|
||||
Dave Tucker <dave@dtucker.co.uk>
|
||||
Davide Agnello <dagnello@hp.com>
|
||||
David Stark <dave@davidstark.name>
|
||||
Deric Crago <deric.crago@gmail.com>
|
||||
Doug MacEachern <dougm@vmware.com>
|
||||
Eloy Coto <eloy.coto@gmail.com>
|
||||
Eric Gray <egray@vmware.com>
|
||||
Eric Yutao <eric.yutao@gmail.com>
|
||||
Erik Hollensbe <github@hollensbe.org>
|
||||
Fabio Rapposelli <fabio@vmware.com>
|
||||
Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
forkbomber <forkbomber@users.noreply.github.com>
|
||||
Gavin Gray <gavin@infinio.com>
|
||||
Gavrie Philipson <gavrie.philipson@elastifile.com>
|
||||
George Hicken <ghicken@vmware.com>
|
||||
Gerrit Renker <Gerrit.Renker@ctl.io>
|
||||
gthombare <gthombare@vmware.com>
|
||||
Hasan Mahmood <mahmoodh@vmware.com>
|
||||
Henrik Hodne <henrik@travis-ci.com>
|
||||
Isaac Rodman <isaac@eyz.us>
|
||||
Ivan Porto Carrero <icarrero@vmware.com>
|
||||
Jason Kincl <jkincl@gmail.com>
|
||||
Jeremy Canady <jcanady@jackhenry.com>
|
||||
jeremy-clerc <jeremy@clerc.io>
|
||||
João Pereira <joaodrp@gmail.com>
|
||||
Jorge Sevilla <jorge.sevilla@rstor.io>
|
||||
leslie-qiwa <leslie.qiwa@gmail.com>
|
||||
Louie Jiang <jiangl@vmware.com>
|
||||
Marc Carmier <mcarmier@gmail.com>
|
||||
Matthew Cosgrove <matthew.cosgrove@dell.com>
|
||||
Mevan Samaratunga <mevansam@gmail.com>
|
||||
Nicolas Lamirault <nicolas.lamirault@gmail.com>
|
||||
Omar Kohl <omarkohl@gmail.com>
|
||||
Parham Alvani <parham.alvani@gmail.com>
|
||||
Pieter Noordhuis <pnoordhuis@vmware.com>
|
||||
runner.mei <runner.mei@gmail.com>
|
||||
S.Çağlar Onur <conur@vmware.com>
|
||||
Sergey Ignatov <sergey.ignatov@jetbrains.com>
|
||||
Steve Purcell <steve@sanityinc.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com>
|
||||
tanishi <tanishi503@gmail.com>
|
||||
Ted Zlatanov <tzz@lifelogs.com>
|
||||
Thibaut Ackermann <thibaut.ackermann@alcatel-lucent.com>
|
||||
Trevor Dawe <trevor.dawe@gmail.com>
|
||||
Vadim Egorov <vegorov@vmware.com>
|
||||
Volodymyr Bobyr <pupsua@gmail.com>
|
||||
Witold Krecicki <wpk@culm.net>
|
||||
Yang Yang <yangy@vmware.com>
|
||||
Yuya Kusakabe <yuya.kusakabe@gmail.com>
|
||||
Zach Tucker <ztucker@vmware.com>
|
||||
Zee Yang <zeey@vmware.com>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
FROM scratch
|
||||
LABEL maintainer="fabio@vmware.com"
|
||||
COPY govc /
|
||||
ENTRYPOINT [ "/govc" ]
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "improvements"
|
||||
name = "github.com/davecgh/go-xdr"
|
||||
packages = ["xdr2"]
|
||||
revision = "4930550ba2e22f87187498acfd78348b15f4e7a8"
|
||||
source = "https://github.com/rasky/go-xdr"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/uuid"
|
||||
packages = ["."]
|
||||
revision = "6a5e28554805e78ea6141142aba763936c4761c0"
|
||||
|
||||
[[projects]]
|
||||
branch = "govmomi"
|
||||
name = "github.com/kr/pretty"
|
||||
packages = ["."]
|
||||
revision = "2ee9d7453c02ef7fa518a83ae23644eb8872186a"
|
||||
source = "https://github.com/dougm/pretty"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/kr/text"
|
||||
packages = ["."]
|
||||
revision = "7cafcd837844e784b526369c9bce262804aebc60"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/vmware/vmw-guestinfo"
|
||||
packages = [
|
||||
"bdoor",
|
||||
"message",
|
||||
"vmcheck"
|
||||
]
|
||||
revision = "25eff159a728be87e103a0b8045e08273f4dbec4"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "376638fa6c0621cbd980caf8fc53494d880886f100663da8de47ecb6e596e439"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# Refer to https://github.com/toml-lang/toml for detailed TOML docs.
|
||||
|
||||
[prune]
|
||||
non-go = true
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
branch = "improvements"
|
||||
name = "github.com/davecgh/go-xdr"
|
||||
source = "https://github.com/rasky/go-xdr"
|
||||
|
||||
[[constraint]]
|
||||
branch = "govmomi"
|
||||
name = "github.com/kr/pretty"
|
||||
source = "https://github.com/dougm/pretty"
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
.PHONY: test
|
||||
|
||||
all: check test
|
||||
|
||||
check: goimports govet
|
||||
|
||||
goimports:
|
||||
@echo checking go imports...
|
||||
@go get golang.org/x/tools/cmd/goimports
|
||||
@! goimports -d . 2>&1 | egrep -v '^$$'
|
||||
|
||||
govet:
|
||||
@echo checking go vet...
|
||||
@go tool vet -structtags=false -methods=false $$(find . -mindepth 1 -maxdepth 1 -type d -not -name vendor)
|
||||
|
||||
install:
|
||||
go install -v github.com/vmware/govmomi/govc
|
||||
go install -v github.com/vmware/govmomi/vcsim
|
||||
|
||||
go-test:
|
||||
GORACE=history_size=5 go test -timeout 5m -count 1 -race -v $(TEST_OPTS) ./...
|
||||
|
||||
govc-test: install
|
||||
(cd govc/test && ./vendor/github.com/sstephenson/bats/libexec/bats -t .)
|
||||
|
||||
test: go-test govc-test
|
||||
|
||||
doc: install
|
||||
./govc/usage.sh > ./govc/USAGE.md
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
[](https://travis-ci.org/vmware/govmomi)
|
||||
[](https://goreportcard.com/report/github.com/vmware/govmomi)
|
||||
|
||||
# govmomi
|
||||
|
||||
A Go library for interacting with VMware vSphere APIs (ESXi and/or vCenter).
|
||||
|
||||
In addition to the vSphere API client, this repository includes:
|
||||
|
||||
* [govc](./govc) - vSphere CLI
|
||||
|
||||
* [vcsim](./vcsim) - vSphere API mock framework
|
||||
|
||||
* [toolbox](./toolbox) - VM guest tools framework
|
||||
|
||||
## Compatibility
|
||||
|
||||
This library is built for and tested against ESXi and vCenter 6.0, 6.5 and 6.7.
|
||||
|
||||
It may work with versions 5.5 and 5.1, but neither are officially supported.
|
||||
|
||||
## Documentation
|
||||
|
||||
The APIs exposed by this library very closely follow the API described in the [VMware vSphere API Reference Documentation][apiref].
|
||||
Refer to this document to become familiar with the upstream API.
|
||||
|
||||
The code in the `govmomi` package is a wrapper for the code that is generated from the vSphere API description.
|
||||
It primarily provides convenience functions for working with the vSphere API.
|
||||
See [godoc.org][godoc] for documentation.
|
||||
|
||||
[apiref]:http://pubs.vmware.com/vsphere-6-5/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
|
||||
[godoc]:http://godoc.org/github.com/vmware/govmomi
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
go get -u github.com/vmware/govmomi
|
||||
```
|
||||
|
||||
## Discussion
|
||||
|
||||
Contributors and users are encouraged to collaborate using GitHub issues and/or
|
||||
[Slack](https://vmwarecode.slack.com/messages/govmomi).
|
||||
Access to Slack requires a [VMware {code} membership](https://code.vmware.com/join/).
|
||||
|
||||
## Status
|
||||
|
||||
Changes to the API are subject to [semantic versioning](http://semver.org).
|
||||
|
||||
Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
|
||||
|
||||
## Projects using govmomi
|
||||
|
||||
* [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere)
|
||||
|
||||
* [Docker InfraKit](https://github.com/docker/infrakit/tree/master/pkg/provider/vsphere)
|
||||
|
||||
* [Docker LinuxKit](https://github.com/linuxkit/linuxkit/tree/master/src/cmd/linuxkit)
|
||||
|
||||
* [Kubernetes](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/vsphere)
|
||||
|
||||
* [Kubernetes kops](https://github.com/kubernetes/kops/tree/master/upup/pkg/fi/cloudup/vsphere)
|
||||
|
||||
* [Terraform](https://github.com/terraform-providers/terraform-provider-vsphere)
|
||||
|
||||
* [Packer](https://github.com/jetbrains-infra/packer-builder-vsphere)
|
||||
|
||||
* [VMware VIC Engine](https://github.com/vmware/vic)
|
||||
|
||||
* [Travis CI](https://github.com/travis-ci/jupiter-brain)
|
||||
|
||||
* [collectd-vsphere](https://github.com/travis-ci/collectd-vsphere)
|
||||
|
||||
* [Gru](https://github.com/dnaeon/gru)
|
||||
|
||||
* [Libretto](https://github.com/apcera/libretto/tree/master/virtualmachine/vsphere)
|
||||
|
||||
## Related projects
|
||||
|
||||
* [rbvmomi](https://github.com/vmware/rbvmomi)
|
||||
|
||||
* [pyvmomi](https://github.com/vmware/pyvmomi)
|
||||
|
||||
## License
|
||||
|
||||
govmomi is available under the [Apache 2 license](LICENSE).
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright (c) 2014-2016 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This package is the root package of the govmomi library.
|
||||
|
||||
The library is structured as follows:
|
||||
|
||||
Package vim25
|
||||
|
||||
The minimal usable functionality is available through the vim25 package.
|
||||
It contains subpackages that contain generated types, managed objects, and all
|
||||
available methods. The vim25 package is entirely independent of the other
|
||||
packages in the govmomi tree -- it has no dependencies on its peers.
|
||||
|
||||
The vim25 package itself contains a client structure that is
|
||||
passed around throughout the entire library. It abstracts a session and its
|
||||
immutable state. See the vim25 package for more information.
|
||||
|
||||
Package session
|
||||
|
||||
The session package contains an abstraction for the session manager that allows
|
||||
a user to login and logout. It also provides access to the current session
|
||||
(i.e. to determine if the user is in fact logged in)
|
||||
|
||||
Package object
|
||||
|
||||
The object package contains wrappers for a selection of managed objects. The
|
||||
constructors of these objects all take a *vim25.Client, which they pass along
|
||||
to derived objects, if applicable.
|
||||
|
||||
Package govc
|
||||
|
||||
The govc package contains the govc CLI. The code in this tree is not intended
|
||||
to be used as a library. Any functionality that govc contains that _could_ be
|
||||
used as a library function but isn't, _should_ live in a root level package.
|
||||
|
||||
Other packages
|
||||
|
||||
Other packages, such as "event", "guest", or "license", provide wrappers for
|
||||
the respective subsystems. They are typically not needed in normal workflows so
|
||||
are kept outside the object package.
|
||||
*/
|
||||
package govmomi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/session"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
*vim25.Client
|
||||
|
||||
SessionManager *session.Manager
|
||||
}
|
||||
|
||||
// NewClient creates a new client from a URL. The client authenticates with the
|
||||
// server with username/password before returning if the URL contains user information.
|
||||
func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error) {
|
||||
soapClient := soap.NewClient(u, insecure)
|
||||
vimClient, err := vim25.NewClient(ctx, soapClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Client{
|
||||
Client: vimClient,
|
||||
SessionManager: session.NewManager(vimClient),
|
||||
}
|
||||
|
||||
// Only login if the URL contains user information.
|
||||
if u.User != nil {
|
||||
err = c.Login(ctx, u.User)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Login dispatches to the SessionManager.
|
||||
func (c *Client) Login(ctx context.Context, u *url.Userinfo) error {
|
||||
return c.SessionManager.Login(ctx, u)
|
||||
}
|
||||
|
||||
// Logout dispatches to the SessionManager.
|
||||
func (c *Client) Logout(ctx context.Context) error {
|
||||
// Close any idle connections after logging out.
|
||||
defer c.Client.CloseIdleConnections()
|
||||
return c.SessionManager.Logout(ctx)
|
||||
}
|
||||
|
||||
// PropertyCollector returns the session's default property collector.
|
||||
func (c *Client) PropertyCollector() *property.Collector {
|
||||
return property.DefaultCollector(c.Client)
|
||||
}
|
||||
|
||||
// RetrieveOne dispatches to the Retrieve function on the default property collector.
|
||||
func (c *Client) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, p []string, dst interface{}) error {
|
||||
return c.PropertyCollector().RetrieveOne(ctx, obj, p, dst)
|
||||
}
|
||||
|
||||
// Retrieve dispatches to the Retrieve function on the default property collector.
|
||||
func (c *Client) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, p []string, dst interface{}) error {
|
||||
return c.PropertyCollector().Retrieve(ctx, objs, p, dst)
|
||||
}
|
||||
|
||||
// Wait dispatches to property.Wait.
|
||||
func (c *Client) Wait(ctx context.Context, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
|
||||
return property.Wait(ctx, c.PropertyCollector(), obj, ps, f)
|
||||
}
|
||||
|
||||
// IsVC returns true if we are connected to a vCenter
|
||||
func (c *Client) IsVC() bool {
|
||||
return c.Client.IsVC()
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
# These tests should only run against a server running an evaluation license.
|
||||
verify_evaluation() {
|
||||
if [ "$(govc license.ls -json | jq -r .[0].EditionKey)" != "eval" ]; then
|
||||
skip "requires evaluation license"
|
||||
fi
|
||||
}
|
||||
|
||||
get_key() {
|
||||
jq ".[] | select(.LicenseKey == \"$1\")"
|
||||
}
|
||||
|
||||
get_property() {
|
||||
jq -r ".Properties[] | select(.Key == \"$1\") | .Value"
|
||||
}
|
||||
|
||||
@test "license.add" {
|
||||
esx_env
|
||||
|
||||
verify_evaluation
|
||||
|
||||
run govc license.add -json 00000-00000-00000-00000-00001 00000-00000-00000-00000-00002
|
||||
assert_success
|
||||
|
||||
# Expect to see an entry for both the first and the second key
|
||||
assert_equal "License is not valid for this product" "$(get_key 00000-00000-00000-00000-00001 <<<${output} | get_property diagnostic)"
|
||||
assert_equal "License is not valid for this product" "$(get_key 00000-00000-00000-00000-00002 <<<${output} | get_property diagnostic)"
|
||||
}
|
||||
|
||||
@test "license.remove" {
|
||||
esx_env
|
||||
|
||||
verify_evaluation
|
||||
|
||||
run govc license.remove -json 00000-00000-00000-00000-00001
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "license.ls" {
|
||||
vcsim_env
|
||||
|
||||
verify_evaluation
|
||||
|
||||
run govc license.ls -json
|
||||
assert_success
|
||||
|
||||
# Expect the test instance to run in evaluation mode
|
||||
assert_equal "Evaluation Mode" "$(get_key 00000-00000-00000-00000-00000 <<<$output | jq -r ".Name")"
|
||||
}
|
||||
|
||||
@test "license.decode" {
|
||||
esx_env
|
||||
|
||||
verify_evaluation
|
||||
|
||||
key=00000-00000-00000-00000-00000
|
||||
assert_equal "eval" $(govc license.decode $key | grep $key | awk '{print $2}')
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user