Merge branch 'release/2.0.0' of ssh://git.yunion.io/~qiujian/onecloud into hotfix/qj-misc-bugfix-20180808

This commit is contained in:
Qiu Jian
2018-08-09 00:44:45 +08:00
208 changed files with 103417 additions and 149 deletions
Generated
+23 -1
View File
@@ -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
+5
View File
@@ -80,3 +80,8 @@
[prune]
go-tests = true
unused-packages = true
[[constraint]]
branch = "master"
name = "github.com/vmware/govmomi"
+6 -4
View File
@@ -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 -4
View File
@@ -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)
}
+118
View File
@@ -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)
}
}
}
}
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -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"
)
+4 -4
View File
@@ -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"
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
+3
View File
@@ -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)
}
+2
View File
@@ -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")
+1 -1
View File
@@ -130,7 +130,7 @@ type ICloudVM interface {
GetEIP() ICloudEIP
// GetStatus() string
GetRemoteStatus() string
// GetRemoteStatus() string
GetVcpuCount() int8
GetVmemSizeMB() int //MB
+1 -23
View File
@@ -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
}
-9
View File
@@ -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
}
+23 -1
View File
@@ -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
}
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+57 -13
View File
@@ -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)
}
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
)
+1
View File
@@ -7,6 +7,7 @@ import (
func InitDB() error {
for _, manager := range []db.IModelManager{
CloudproviderManager,
CloudregionManager,
ZoneManager,
VpcManager,
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
)
+1 -1
View File
@@ -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"
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
)
+1
View File
@@ -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() {
+2 -2
View File
@@ -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 {
+4 -4
View File
@@ -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"
)
+1 -1
View File
@@ -114,4 +114,4 @@ func NewYunionAgentManager(keyword, keywordPlural string, columns, adminColumns
adminColumns: adminColumns,
serviceType: "yunionagent"},
Keyword: keyword, KeywordPlural: keywordPlural}
}
}
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -21,9 +21,9 @@ func getUpdate(d []interface{}) ([]string, error) {
func defaultSyncItems() []cache.CachedItem {
return []cache.CachedItem{
//newGlanceCache(),
//newNetworkCache(),
//newNetworksDataCache(),
//newGlanceCache(),
//newNetworkCache(),
//newNetworksDataCache(),
}
}
+2 -1
View File
@@ -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"
+5 -2
View File
@@ -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 -1
View File
@@ -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
+3 -2
View File
@@ -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)
})
}
+7 -6
View File
@@ -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
+3 -2
View File
@@ -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
+3 -2
View File
@@ -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
+7 -6
View File
@@ -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
+11
View File
@@ -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 -1
View File
@@ -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 -2
View File
@@ -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
+3 -2
View File
@@ -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
+5 -2
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+2 -2
View File
@@ -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 {
+78
View File
@@ -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
}
+360
View File
@@ -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
}
+234
View File
@@ -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)
}
+22
View File
@@ -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())
}
}
}
+124
View File
@@ -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:]
}
+14
View File
@@ -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)
}
+117
View File
@@ -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
}
+19
View File
@@ -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
})
}
+36
View File
@@ -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
})
}
+24
View File
@@ -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
})
}
+11
View File
@@ -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)
}
+59
View File
@@ -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
})
}
+88
View File
@@ -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
}
+207
View File
@@ -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
}
+60
View File
@@ -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
View File
@@ -0,0 +1,2 @@
secrets.yml
dist/
+57
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -0,0 +1,4 @@
FROM scratch
LABEL maintainer="fabio@vmware.com"
COPY govc /
ENTRYPOINT [ "/govc" ]
+44
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -0,0 +1,86 @@
[![Build Status](https://travis-ci.org/vmware/govmomi.png?branch=master)](https://travis-ci.org/vmware/govmomi)
[![Go Report Card](https://goreportcard.com/badge/github.com/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
View File
@@ -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
View File
@@ -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