mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #70 in YUNIONIO/onecloud from ~LIZEXI/onecloud:hotfix/lzx-resolve-conflict-2.1.0-2018-08-17 to release/2.1.0
* commit '13aa7b81e97bec8fe41aff9f4cb8cbb7169a674e': - climc: 设置 option 没有 subcommand 的情况下进入交互模式, 代码逻辑变清晰 - make fmt
This commit is contained in:
Generated
+1
-1
@@ -908,7 +908,7 @@
|
||||
branch = "master"
|
||||
name = "yunion.io/x/structarg"
|
||||
packages = ["."]
|
||||
revision = "adf929ce0f8bd62335ebe57d9b51f023c84e4d7a"
|
||||
revision = "d5e5d87357b9bc2164215117763f6b15b2a3e75d"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
|
||||
+68
-42
@@ -169,6 +169,40 @@ func newClientSession(options *BaseOptions) (*mcclient.ClientSession, error) {
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func enterInteractiveMode(
|
||||
parser *structarg.ArgumentParser,
|
||||
sessionFactory func() *mcclient.ClientSession,
|
||||
) {
|
||||
promputils.InitEnv(parser, sessionFactory())
|
||||
defer fmt.Println("Bye!")
|
||||
p := prompt.New(
|
||||
promputils.Executor,
|
||||
promputils.Completer,
|
||||
prompt.OptionPrefix("climc> "),
|
||||
prompt.OptionTitle("Climc, a Command Line Interface to Manage Clouds"),
|
||||
prompt.OptionMaxSuggestion(16),
|
||||
)
|
||||
p.Run()
|
||||
}
|
||||
|
||||
func executeSubcommand(
|
||||
subcmd *structarg.SubcommandArgument,
|
||||
subparser *structarg.ArgumentParser,
|
||||
options *BaseOptions,
|
||||
sessionFactory func() *mcclient.ClientSession,
|
||||
) {
|
||||
var e error
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
e = subcmd.Invoke(sessionFactory(), suboptions)
|
||||
}
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
parser, e := getSubcommandsParser()
|
||||
if e != nil {
|
||||
@@ -179,47 +213,39 @@ func main() {
|
||||
|
||||
if options.Help {
|
||||
fmt.Print(parser.HelpString())
|
||||
} else if options.Version {
|
||||
fmt.Printf("Yunion API client version:\n %s\n", version.GetJsonString())
|
||||
} else if len(os.Args) <= 1 || (options.ApiVersion == "v2" && len(os.Args) <= 3) {
|
||||
session, e := newClientSession(options)
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
promputils.InitEnv(parser, session)
|
||||
defer fmt.Println("Bye!")
|
||||
p := prompt.New(
|
||||
promputils.Executor,
|
||||
promputils.Completer,
|
||||
prompt.OptionPrefix("climc> "),
|
||||
prompt.OptionTitle("Climc, a Command Line Interface to Manage Clouds"),
|
||||
prompt.OptionMaxSuggestion(16),
|
||||
)
|
||||
p.Run()
|
||||
} 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 {
|
||||
session, e := newClientSession(options)
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
e = subcmd.Invoke(session, suboptions)
|
||||
}
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if options.Version {
|
||||
fmt.Printf("Yunion API client version:\n %s\n", version.GetJsonString())
|
||||
return
|
||||
}
|
||||
|
||||
ensureSessionFactory := func() *mcclient.ClientSession {
|
||||
session, err := newClientSession(options)
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
||||
// enter interactive mode when not enough argument and SUBCOMMAND is empty
|
||||
if _, ok := e.(*structarg.NotEnoughArgumentsError); ok && options.SUBCOMMAND == "" {
|
||||
enterInteractiveMode(parser, ensureSessionFactory)
|
||||
return
|
||||
}
|
||||
|
||||
subcmd := parser.GetSubcommand()
|
||||
subparser := subcmd.GetSubParser()
|
||||
if e != nil {
|
||||
if subparser != nil {
|
||||
fmt.Print(subparser.Usage())
|
||||
} else {
|
||||
fmt.Print(parser.Usage())
|
||||
}
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
|
||||
// execute subcommand in non-interactive mode
|
||||
executeSubcommand(subcmd, subparser, options, ensureSessionFactory)
|
||||
}
|
||||
|
||||
@@ -140,12 +140,12 @@ func init() {
|
||||
})
|
||||
|
||||
type CloudproviderSyncOptions struct {
|
||||
ID string `help:"ID or Name of cloud provider"`
|
||||
Force bool `help:"Force sync no matter what"`
|
||||
FullSync bool `help:"Synchronize everything"`
|
||||
Region []string `help:"region to sync"`
|
||||
Zone []string `help:"region to sync"`
|
||||
Host []string `help:"region to sync"`
|
||||
ID string `help:"ID or Name of cloud provider"`
|
||||
Force bool `help:"Force sync no matter what"`
|
||||
FullSync bool `help:"Synchronize everything"`
|
||||
Region []string `help:"region to sync"`
|
||||
Zone []string `help:"region to sync"`
|
||||
Host []string `help:"region to sync"`
|
||||
}
|
||||
R(&CloudproviderSyncOptions{}, "cloud-provider-sync", "Sync of a cloud provider account", func(s *mcclient.ClientSession, args *CloudproviderSyncOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/prometheus"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
|
||||
o "yunion.io/x/onecloud/cmd/scheduler/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
|
||||
@@ -27,6 +27,7 @@ const (
|
||||
|
||||
CLOUD_PROVIDER_VMWARE = "VMware"
|
||||
CLOUD_PROVIDER_ALIYUN = "Aliyun"
|
||||
CLOUD_PROVIDER_AZURE = "Azure"
|
||||
)
|
||||
|
||||
type SCloudproviderManager struct {
|
||||
|
||||
@@ -145,9 +145,9 @@ func (manager *SCloudregionManager) SyncRegions(ctx context.Context, userCred mc
|
||||
_, err = removed[i].PerformDisable(ctx, userCred, nil, nil)
|
||||
}
|
||||
if err != nil {
|
||||
syncResult.Delete()
|
||||
} else {
|
||||
syncResult.DeleteError(err)
|
||||
} else {
|
||||
syncResult.Delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ const (
|
||||
HYPERVISOR_ESXI = "esxi"
|
||||
HYPERVISOR_HYPERV = "hyperv"
|
||||
HYPERVISOR_ALIYUN = "aliyun"
|
||||
HYPERVISOR_AZURE = "azure"
|
||||
|
||||
// HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
HYPERVISOR_DEFAULT = HYPERVISOR_ALIYUN
|
||||
|
||||
@@ -35,6 +35,7 @@ const (
|
||||
HOST_TYPE_HYPERV = "hyperv" // # Microsoft Hyper-V
|
||||
HOST_TYPE_XEN = "xen" // # XenServer
|
||||
HOST_TYPE_ALIYUN = "aliyun"
|
||||
HOST_TYPE_AZURE = "azure"
|
||||
|
||||
HOST_TYPE_DEFAULT = HOST_TYPE_HYPERVISOR
|
||||
|
||||
|
||||
@@ -826,7 +826,11 @@ func isValidMaskLen(maskLen int64) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
func (manager *SNetworkManager) AllowPerformCheckNet(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) PerformCheckNet(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
prefixStr, _ := data.GetString("guest_ip_prefix")
|
||||
var maskLen64 int64
|
||||
var err error
|
||||
@@ -962,7 +966,13 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
if !vpcRange.ContainsRange(netRange) {
|
||||
return nil, httperrors.NewInputParameterError("Network not in range of VPC cidrblock %s", vpc.CidrBlock)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
if _, err := manager.PerformCheckNet(ctx, userCred, query, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serverTypeStr, _ := data.GetString("server_type")
|
||||
if len(serverTypeStr) == 0 {
|
||||
serverTypeStr = SERVER_TYPE_GUEST
|
||||
|
||||
@@ -290,6 +290,7 @@ func (manager *SStorageManager) SyncStorages(ctx context.Context, userCred mccli
|
||||
added := make([]cloudprovider.ICloudStorage, 0)
|
||||
|
||||
err = compare.CompareSets(dbStorages, storages, &removed, &commondb, &commonext, &added)
|
||||
|
||||
if err != nil {
|
||||
syncResult.Error(err)
|
||||
return nil, nil, syncResult
|
||||
|
||||
@@ -21,10 +21,10 @@ type ComputeOptions struct {
|
||||
|
||||
DefaultDiskSize int `default:"30720" help:"Default disk size in MB if not specified, default to 30GiB"`
|
||||
|
||||
EnablePendingDelete bool `default:"true" help:"Turn on/off pending delete VM and disk, default is on"`
|
||||
PendingDeleteCheckSeconds int `default:"3600" help:"How long to wait to scan pending delete VM or disks, default is 1 hour"`
|
||||
PendingDeleteExpireSeconds int `default:"259200" help:"How long a pending delete VM/disks cleaned automatically, default 3 days"`
|
||||
PendingDeleteMaxCleanBatchSize int `default:"50" help:"How many pending delete servers can be clean in a batch"`
|
||||
EnablePendingDelete bool `default:"true" help:"Turn on/off pending delete VM and disk, default is on"`
|
||||
PendingDeleteCheckSeconds int `default:"3600" help:"How long to wait to scan pending delete VM or disks, default is 1 hour"`
|
||||
PendingDeleteExpireSeconds int `default:"259200" help:"How long a pending delete VM/disks cleaned automatically, default 3 days"`
|
||||
PendingDeleteMaxCleanBatchSize int `default:"50" help:"How many pending delete servers can be clean in a batch"`
|
||||
|
||||
ImageCacheStoragePolicy string `default:"least_used" choices:"best_fit|least_used" help:"Policy to choose storage for image cache, best_fit or least_used"`
|
||||
MetricsRetentionDays int32 `default:"30" help:"Retention days for monitoring metrics in influxdb"`
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
_ "yunion.io/x/onecloud/pkg/compute/hostdrivers"
|
||||
_ "yunion.io/x/onecloud/pkg/compute/tasks"
|
||||
_ "yunion.io/x/onecloud/pkg/util/aliyun/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/util/azure/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/util/esxi/provider"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon"
|
||||
|
||||
@@ -9,9 +9,10 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/pkg/utils"
|
||||
)
|
||||
|
||||
type SRegion struct {
|
||||
@@ -564,4 +565,4 @@ func (self *SRegion) updateInstance(instId string, name, desc, passwd, hostname
|
||||
|
||||
func (self *SRegion) UpdateInstancePassword(instId string, passwd string) error {
|
||||
return self.updateInstance(instId, "", "", passwd, "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package shell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/aliyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
@@ -82,7 +83,7 @@ func init() {
|
||||
})
|
||||
|
||||
type InstanceUpdatePasswordOptions struct {
|
||||
ID string `help:"Instance ID"`
|
||||
ID string `help:"Instance ID"`
|
||||
PASSWD string `help:"new password"`
|
||||
}
|
||||
shellutils.R(&InstanceUpdatePasswordOptions{}, "instance-update-password", "Update instance password", func(cli *aliyun.SRegion, args *InstanceUpdatePasswordOptions) error {
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/profiles/latest/resources/mgmt/resources"
|
||||
"github.com/Azure/azure-sdk-for-go/services/preview/subscription/mgmt/2018-03-01-preview/subscription"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure/auth"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
)
|
||||
|
||||
const (
|
||||
CLOUD_PROVIDER_AZURE = models.CLOUD_PROVIDER_AZURE
|
||||
CLOUD_PROVIDER_AZURE_CN = "微软"
|
||||
|
||||
AZURE_DEFAULT_ENVIRONMENT = "AzureChinaCloud"
|
||||
AZURE_DEFAULT_APPLICATION = "Azure-Yunion-API"
|
||||
|
||||
AZURE_API_VERSION = "2014-05-26"
|
||||
)
|
||||
|
||||
type SAzureClient struct {
|
||||
providerId string
|
||||
providerName string
|
||||
subscriptionId string
|
||||
tenantId string
|
||||
clientId string
|
||||
clientScret string
|
||||
baseUrl string
|
||||
secret string
|
||||
resourceGroups map[string][]string
|
||||
authorizer autorest.Authorizer
|
||||
iregions []cloudprovider.ICloudRegion
|
||||
}
|
||||
|
||||
func NewAzureClient(providerId string, providerName string, accessKey string, secret string, url string) (*SAzureClient, error) {
|
||||
url = strings.Replace(url, "login", "management", -1)
|
||||
if clientInfo := strings.Split(secret, "/"); len(clientInfo) == 3 {
|
||||
client := SAzureClient{providerId: providerId, providerName: providerName, tenantId: accessKey, secret: secret, baseUrl: url}
|
||||
client.clientId, client.clientScret, client.subscriptionId = clientInfo[0], clientInfo[1], clientInfo[2]
|
||||
if err := client.fetchAzureInof(); err != nil {
|
||||
return nil, err
|
||||
} else if err := client.fetchRegions(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &client, nil
|
||||
} else {
|
||||
return nil, httperrors.NewUnauthorizedError("clientId、clientScret or subscriptId input error")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureClient) fetchAzureInof() error {
|
||||
conf := auth.NewClientCredentialsConfig(self.clientId, self.clientScret, self.tenantId)
|
||||
conf.Resource = self.baseUrl
|
||||
conf.AADEndpoint = strings.Replace(self.baseUrl, "management", "login", -1)
|
||||
if authorizer, err := conf.Authorizer(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.authorizer = authorizer
|
||||
}
|
||||
resourceClient := resources.NewClientWithBaseURI(self.baseUrl, self.subscriptionId)
|
||||
resourceClient.Authorizer = self.authorizer
|
||||
if resourceList, err := resourceClient.List(context.Background(), "", "", nil); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.resourceGroups = make(map[string][]string, len(resourceList.Values()))
|
||||
for _, resource := range resourceList.Values() {
|
||||
if _, ok := self.resourceGroups[*resource.Type]; !ok {
|
||||
self.resourceGroups[*resource.Type] = []string{}
|
||||
}
|
||||
self.resourceGroups[*resource.Type] = append(self.resourceGroups[*resource.Type], *resource.Name)
|
||||
log.Errorf("find resource group: %s => %s", *resource.Type, *resource.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureClient) UpdateAccount(tenantId, secret string) error {
|
||||
if self.tenantId != tenantId || self.secret != secret {
|
||||
self.tenantId = tenantId
|
||||
self.secret = secret
|
||||
if clientInfo := strings.Split(secret, "/"); len(clientInfo) == 3 {
|
||||
self.clientId, self.clientScret, self.subscriptionId = clientInfo[0], clientInfo[1], clientInfo[2]
|
||||
conf := auth.NewClientCredentialsConfig(self.clientId, self.clientScret, self.tenantId)
|
||||
conf.Resource = self.baseUrl
|
||||
conf.AADEndpoint = strings.Replace(self.baseUrl, "management", "login", -1)
|
||||
if authorizer, err := conf.Authorizer(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.authorizer = authorizer
|
||||
}
|
||||
} else {
|
||||
return httperrors.NewUnauthorizedError("clientId、clientScret or subscriptId input error")
|
||||
}
|
||||
return self.fetchAzureInof()
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureClient) fetchRegions() error {
|
||||
locationClient := subscription.NewSubscriptionsClientWithBaseURI(self.baseUrl)
|
||||
locationClient.Authorizer = self.authorizer
|
||||
if locationList, err := locationClient.ListLocations(context.Background(), self.subscriptionId); err != nil {
|
||||
return err
|
||||
} else {
|
||||
regions := make([]SRegion, len(*locationList.Value))
|
||||
self.iregions = make([]cloudprovider.ICloudRegion, len(regions))
|
||||
for i, location := range *locationList.Value {
|
||||
region := SRegion{SubscriptionID: self.subscriptionId}
|
||||
if err := jsonutils.Update(®ion, location); err != nil {
|
||||
return err
|
||||
}
|
||||
region.client = self
|
||||
self.iregions[i] = ®ion
|
||||
log.Infof("find region: %s", jsonutils.Marshal(region).PrettyString())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetRegions() []SRegion {
|
||||
regions := make([]SRegion, len(self.iregions))
|
||||
for i := 0; i < len(regions); i += 1 {
|
||||
region := self.iregions[i].(*SRegion)
|
||||
regions[i] = *region
|
||||
}
|
||||
return regions
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
return self.iregions
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
if self.iregions[i].GetGlobalId() == id {
|
||||
return self.iregions[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetRegion(regionId string) *SRegion {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
if self.iregions[i].GetId() == regionId {
|
||||
return self.iregions[i].(*SRegion)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIHostById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIVpcById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIStorageById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAzureClient) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIStoragecacheById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute"
|
||||
)
|
||||
|
||||
type StorageAccountTypes string
|
||||
|
||||
const (
|
||||
// StorageAccountTypesPremiumLRS ...
|
||||
StorageAccountTypesPremiumLRS StorageAccountTypes = "Premium_LRS"
|
||||
// StorageAccountTypesStandardLRS ...
|
||||
StorageAccountTypesStandardLRS StorageAccountTypes = "Standard_LRS"
|
||||
// StorageAccountTypesStandardSSDLRS ...
|
||||
StorageAccountTypesStandardSSDLRS StorageAccountTypes = "StandardSSD_LRS"
|
||||
)
|
||||
|
||||
type DiskSku struct {
|
||||
Name StorageAccountTypes
|
||||
Tier string
|
||||
}
|
||||
|
||||
type SDisk struct {
|
||||
storage *SStorage
|
||||
|
||||
DiskName string
|
||||
DiskId string
|
||||
Size int32
|
||||
DeleteWithInstance bool
|
||||
ImageId string
|
||||
OsType string
|
||||
Status string
|
||||
resourceGroup string
|
||||
|
||||
ManagedBy string
|
||||
Sku DiskSku
|
||||
Zones []string
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
Location string
|
||||
|
||||
Tags map[string]string
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisk(resourceGroup string, diskName string) (*SDisk, error) {
|
||||
disk := SDisk{}
|
||||
computeClient := compute.NewDisksClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
computeClient.Authorizer = self.client.authorizer
|
||||
if _disk, err := computeClient.Get(context.Background(), resourceGroup, diskName); err != nil {
|
||||
return nil, err
|
||||
} else if err := jsonutils.Update(&disk, _disk); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &disk, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisks() ([]SDisk, error) {
|
||||
disks := make([]SDisk, 0)
|
||||
computeClient := compute.NewDisksClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
computeClient.Authorizer = self.client.authorizer
|
||||
if diskList, err := computeClient.List(context.Background()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
for _, _disk := range diskList.Values() {
|
||||
disk := SDisk{}
|
||||
if err := jsonutils.Update(&disk, _disk); err != nil {
|
||||
return disks, err
|
||||
}
|
||||
disk.resourceGroup, _, _ = pareResourceGroupWithName(disk.ID)
|
||||
disks = append(disks, disk)
|
||||
}
|
||||
}
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
func (self *SDisk) GetStatus() string {
|
||||
// In_use Available Attaching Detaching Creating ReIniting All
|
||||
switch self.Status {
|
||||
case "Creating", "ReIniting":
|
||||
return models.DISK_ALLOCATING
|
||||
default:
|
||||
return models.DISK_READY
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDisk) GetId() string {
|
||||
return self.DiskId
|
||||
}
|
||||
|
||||
func (self *SRegion) getDisk(resourceGroup string, diskName string) (*SDisk, error) {
|
||||
return self.GetDisk(resourceGroup, diskName)
|
||||
}
|
||||
|
||||
func (self *SDisk) Refresh() error {
|
||||
if disk, err := self.storage.zone.region.GetDisk(self.resourceGroup, self.Name); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return jsonutils.Update(self, disk)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDisk) Delete() error {
|
||||
return nil
|
||||
//return self.storage.zone.region.deleteDisk(self.DiskId)
|
||||
}
|
||||
|
||||
func (self *SDisk) Resize(size int64) error {
|
||||
//return self.storage.zone.region.resizeDisk(self.DiskId, size)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDisk) GetName() string {
|
||||
if len(self.DiskName) > 0 {
|
||||
return self.DiskName
|
||||
}
|
||||
return self.DiskId
|
||||
}
|
||||
|
||||
func (self *SDisk) GetGlobalId() string {
|
||||
return self.DiskId
|
||||
}
|
||||
|
||||
func (self *SDisk) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorge() cloudprovider.ICloudStorage {
|
||||
return self.storage
|
||||
}
|
||||
|
||||
func (self *SDisk) GetFsFormat() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIsNonPersistent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDriver() string {
|
||||
return "scsi"
|
||||
}
|
||||
|
||||
func (self *SDisk) GetCacheMode() string {
|
||||
return "none"
|
||||
}
|
||||
|
||||
func (self *SDisk) GetMountpoint() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskFormat() string {
|
||||
return "vhd"
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskSizeMB() int {
|
||||
return int(self.Size) * 1024
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIsAutoDelete() bool {
|
||||
return self.DeleteWithInstance
|
||||
}
|
||||
|
||||
func (self *SDisk) GetTemplateId() string {
|
||||
return self.ImageId
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskType() string {
|
||||
if len(self.OsType) > 0 {
|
||||
return models.DISK_TYPE_SYS
|
||||
}
|
||||
return models.DISK_TYPE_DATA
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SHost struct {
|
||||
zone *SZone
|
||||
}
|
||||
|
||||
func (self *SHost) GetId() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
|
||||
}
|
||||
|
||||
func (self *SHost) GetName() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.region.Name)
|
||||
}
|
||||
|
||||
func (self *SHost) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", self.zone.region.GetGlobalId(), self.zone.region.SubscriptionID)
|
||||
}
|
||||
|
||||
func (self *SHost) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SHost) GetStatus() string {
|
||||
return models.HOST_STATUS_RUNNING
|
||||
}
|
||||
|
||||
func (self *SHost) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
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) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetAccessIp() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetAccessMac() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuCount() int8 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetCpuMhz() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetMemSizeMB() int {
|
||||
return 0
|
||||
}
|
||||
func (self *SHost) GetEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostStatus() string {
|
||||
return models.HOST_ONLINE
|
||||
}
|
||||
func (self *SHost) GetNodeCount() int8 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostType() string {
|
||||
return models.HOST_TYPE_AZURE
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return self.zone.GetIStorageById(id)
|
||||
}
|
||||
|
||||
func (self *SHost) GetSysInfo() jsonutils.JSONObject {
|
||||
info := jsonutils.NewDict()
|
||||
info.Add(jsonutils.NewString(CLOUD_PROVIDER_AZURE), "manufacture")
|
||||
return info
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
return self.zone.GetIStorages()
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMById(gid string) (cloudprovider.ICloudVM, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetStorageSizeMB() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHost) GetStorageType() string {
|
||||
return models.DISK_TYPE_HYBRID
|
||||
}
|
||||
|
||||
func (self *SHost) GetSN() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
|
||||
if vms, err := self.zone.region.GetInstances(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
ivms := make([]cloudprovider.ICloudVM, len(vms))
|
||||
for i := 0; i < len(vms); i++ {
|
||||
vms[i].host = self
|
||||
ivms[i] = &vms[i]
|
||||
}
|
||||
return ivms, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
return self.zone.GetIWires()
|
||||
}
|
||||
|
||||
func (self *SHost) GetManagerId() string {
|
||||
return self.zone.region.client.providerId
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/pkg/util/osprofile"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute"
|
||||
)
|
||||
|
||||
type HardwareProfile struct {
|
||||
VMSize string
|
||||
MaxDataDiskCount int32
|
||||
MemoryInMB int32
|
||||
NumberOfCores int32
|
||||
Name string
|
||||
OsDiskSizeInMB int32
|
||||
ResourceDiskSizeInMB int32
|
||||
}
|
||||
|
||||
type ImageReference struct {
|
||||
Publisher string
|
||||
Offer string
|
||||
Sku string
|
||||
Version string
|
||||
ID string
|
||||
}
|
||||
|
||||
type OperatingSystemTypes string
|
||||
|
||||
const (
|
||||
// Linux ...
|
||||
Linux OperatingSystemTypes = "Linux"
|
||||
// Windows ...
|
||||
Windows OperatingSystemTypes = "Windows"
|
||||
)
|
||||
|
||||
type OSDisk struct {
|
||||
OsType OperatingSystemTypes
|
||||
Name string
|
||||
DiskSizeGB int32
|
||||
ManagedDisk ManagedDiskParameters
|
||||
}
|
||||
|
||||
type VirtualHardDisk struct {
|
||||
URI string
|
||||
}
|
||||
|
||||
type CachingTypes string
|
||||
|
||||
const (
|
||||
// CachingTypesNone ...
|
||||
CachingTypesNone CachingTypes = "None"
|
||||
// CachingTypesReadOnly ...
|
||||
CachingTypesReadOnly CachingTypes = "ReadOnly"
|
||||
// CachingTypesReadWrite ...
|
||||
CachingTypesReadWrite CachingTypes = "ReadWrite"
|
||||
)
|
||||
|
||||
type ManagedDiskParameters struct {
|
||||
StorageAccountType StorageAccountTypes
|
||||
ID string
|
||||
}
|
||||
|
||||
type DataDisk struct {
|
||||
Lun int32
|
||||
Name string
|
||||
Vhd VirtualHardDisk
|
||||
Caching CachingTypes
|
||||
DiskSizeGB int32
|
||||
ManagedDisk ManagedDiskParameters
|
||||
}
|
||||
|
||||
type StorageProfile struct {
|
||||
ImageReference ImageReference
|
||||
OsDisk OSDisk
|
||||
DataDisks []DataDisk
|
||||
}
|
||||
|
||||
type SSHPublicKey struct {
|
||||
Path string
|
||||
KeyData string
|
||||
}
|
||||
|
||||
type SSHConfiguration struct {
|
||||
PublicKeys []SSHPublicKey
|
||||
}
|
||||
|
||||
type LinuxConfiguration struct {
|
||||
DisablePasswordAuthentication bool
|
||||
SSH SSHConfiguration
|
||||
}
|
||||
|
||||
type SubResource struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
type VaultCertificate struct {
|
||||
CertificateURL string
|
||||
CertificateStore string
|
||||
}
|
||||
|
||||
type VaultSecretGroup struct {
|
||||
SourceVault SubResource
|
||||
VaultCertificates []VaultCertificate
|
||||
}
|
||||
|
||||
type OsProfile struct {
|
||||
ComputerName string
|
||||
AdminUsername string
|
||||
AdminPassword string
|
||||
CustomData string
|
||||
LinuxConfiguration LinuxConfiguration
|
||||
Secrets []VaultSecretGroup
|
||||
}
|
||||
|
||||
type NetworkInterfaceReference struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
type NetworkProfile struct {
|
||||
NetworkInterfaces []NetworkInterfaceReference
|
||||
}
|
||||
|
||||
type InstanceViewStatus struct {
|
||||
Code string
|
||||
Level string
|
||||
DisplayStatus string
|
||||
Message string
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
type VirtualMachineInstanceView struct {
|
||||
ComputerName string
|
||||
OsName string
|
||||
OsVersion string
|
||||
Statuses []InstanceViewStatus
|
||||
}
|
||||
|
||||
type VirtualMachineProperties struct {
|
||||
HardwareProfile HardwareProfile
|
||||
StorageProfile StorageProfile
|
||||
OsProfile OsProfile
|
||||
NetworkProfile NetworkProfile
|
||||
InstanceView VirtualMachineInstanceView
|
||||
VmId string
|
||||
}
|
||||
|
||||
type SInstance struct {
|
||||
host *SHost
|
||||
|
||||
idisks []cloudprovider.ICloudDisk
|
||||
|
||||
CreationTime time.Time
|
||||
ResourceGroup string
|
||||
|
||||
Properties VirtualMachineProperties
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
Location string
|
||||
Tags map[string]string
|
||||
}
|
||||
|
||||
func pareResourceGroupWithName(s string) (string, string, error) {
|
||||
valid := regexp.MustCompile("resourceGroups/(.+)/providers/.+/(.+)$")
|
||||
if resourceGroups := valid.FindStringSubmatch(s); len(resourceGroups) == 3 {
|
||||
return resourceGroups[1], resourceGroups[2], nil
|
||||
}
|
||||
return "", "", cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstance(resourceGroup string, VMName string) (*SInstance, error) {
|
||||
instance := SInstance{}
|
||||
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
computeClient.Authorizer = self.client.authorizer
|
||||
if _instance, err := computeClient.Get(context.Background(), resourceGroup, VMName, "instanceView"); err != nil {
|
||||
return nil, err
|
||||
} else if err := jsonutils.Update(&instance, _instance); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
instance.ResourceGroup = resourceGroup
|
||||
log.Infof("instance: %s", jsonutils.Marshal(instance).PrettyString())
|
||||
return &instance, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstances() ([]SInstance, error) {
|
||||
instances := make([]SInstance, 0)
|
||||
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
computeClient.Authorizer = self.client.authorizer
|
||||
if instanceList, err := computeClient.ListAll(context.Background()); err != nil {
|
||||
return instances, err
|
||||
} else {
|
||||
for _, _instance := range instanceList.Values() {
|
||||
instance := SInstance{}
|
||||
if *_instance.Location == self.Name {
|
||||
if err := jsonutils.Update(&instance, _instance); err != nil {
|
||||
return instances, err
|
||||
}
|
||||
if vmSize, err := self.getVMSize(instance.Properties.HardwareProfile.VMSize); err != nil {
|
||||
return instances, err
|
||||
} else if err := jsonutils.Update(&instance.Properties.HardwareProfile, vmSize); err != nil {
|
||||
return instances, err
|
||||
}
|
||||
instance.ResourceGroup, _, _ = pareResourceGroupWithName(instance.ID)
|
||||
log.Infof("GetInstances: %s", jsonutils.Marshal(&instance).PrettyString())
|
||||
instances = append(instances, instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
return instances, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) doDeleteVM(instanceId string) error {
|
||||
//return self.instanceOperation(instanceId, "DeleteInstance", nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetHypervisor() string {
|
||||
return models.HYPERVISOR_AZURE
|
||||
}
|
||||
|
||||
func (self *SInstance) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstance) Refresh() error {
|
||||
if instance, err := self.host.zone.region.GetInstance(self.ResourceGroup, self.Name); err != nil {
|
||||
log.Errorf("Refresh Instance error: %v", err)
|
||||
return err
|
||||
} else if err := jsonutils.Update(self, instance); err != nil {
|
||||
log.Errorf("Refresh Instance error: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetStatus() string {
|
||||
// Running:运行中
|
||||
//Starting:启动中
|
||||
//Stopping:停止中
|
||||
//Stopped:已停止
|
||||
if len(self.Properties.InstanceView.Statuses) == 0 {
|
||||
self.Refresh()
|
||||
}
|
||||
for _, statuses := range self.Properties.InstanceView.Statuses {
|
||||
if code := strings.Split(statuses.Code, "/"); len(code) == 2 {
|
||||
if code[0] == "PowerState" {
|
||||
return code[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return models.VM_UNKNOWN
|
||||
}
|
||||
|
||||
func (self *SInstance) GetIHost() cloudprovider.ICloudHost {
|
||||
return self.host
|
||||
}
|
||||
|
||||
func (self *SInstance) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SInstance) GetName() string {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
func (self *SInstance) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", self.host.zone.region.GetGlobalId(), self.Properties.VmId)
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteVM(instanceId string) error {
|
||||
// status, err := self.GetInstanceStatus(instanceId)
|
||||
// if status == InstanceStatusRunning {
|
||||
// err = self.StopVM(instanceId, true)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// } else if status != InstanceStatusStopped {
|
||||
// return cloudprovider.ErrInvalidStatus
|
||||
// }
|
||||
return self.doDeleteVM(instanceId)
|
||||
}
|
||||
|
||||
func (self *SInstance) DeleteVM() error {
|
||||
return nil
|
||||
// err := self.host.zone.region.DeleteVM(self.InstanceId)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return cloudprovider.WaitDeleted(self, 10*time.Second, 300*time.Second) // 5minutes
|
||||
}
|
||||
|
||||
func (self *SInstance) getDiskWithStore(resourceGroup string, diskName string) (*SDisk, error) {
|
||||
if disk, err := self.host.zone.region.GetDisk(resourceGroup, diskName); err != nil {
|
||||
return nil, err
|
||||
} else if store, err := self.host.zone.getStorageByTier(disk.Sku.Tier); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
disk.storage = store
|
||||
return disk, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SInstance) fetchDisks() error {
|
||||
self.Refresh()
|
||||
self.idisks = make([]cloudprovider.ICloudDisk, len(self.Properties.StorageProfile.DataDisks)+1)
|
||||
if disk, err := self.getDiskWithStore(self.ResourceGroup, self.Properties.StorageProfile.OsDisk.Name); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.idisks[0] = disk
|
||||
}
|
||||
for i, dataDisk := range self.Properties.StorageProfile.DataDisks {
|
||||
if resourceGroup, diskName, err := pareResourceGroupWithName(dataDisk.ManagedDisk.ID); err != nil {
|
||||
return err
|
||||
} else if disk, err := self.getDiskWithStore(resourceGroup, diskName); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.idisks[i+1] = disk
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
if self.idisks == nil {
|
||||
if err := self.fetchDisks(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.idisks, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetOSType() string {
|
||||
return osprofile.NormalizeOSType(self.Properties.InstanceView.OsName)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
|
||||
nics := make([]cloudprovider.ICloudNic, 0)
|
||||
for _, _nic := range self.Properties.NetworkProfile.NetworkInterfaces {
|
||||
if resourceGroup, nicName, err := pareResourceGroupWithName(_nic.ID); err != nil {
|
||||
return nics, err
|
||||
} else if nic, err := self.host.zone.region.getNetworkInterface(resourceGroup, nicName); err != nil {
|
||||
return nics, err
|
||||
} else {
|
||||
nic.instance = self
|
||||
nics = append(nics, nic)
|
||||
}
|
||||
}
|
||||
return nics, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetOSName() string {
|
||||
return self.Properties.StorageProfile.ImageReference.Offer
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBios() string {
|
||||
return "BIOS"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetMachine() string {
|
||||
return "pc"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetBootOrder() string {
|
||||
return "dcn"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVga() string {
|
||||
return "std"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVdi() string {
|
||||
return "vnc"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVcpuCount() int8 {
|
||||
return int8(self.Properties.HardwareProfile.NumberOfCores)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVmemSizeMB() int {
|
||||
return int(self.Properties.HardwareProfile.MemoryInMB)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetCreateTime() time.Time {
|
||||
return self.CreationTime
|
||||
}
|
||||
|
||||
func (self *SInstance) GetEIP() cloudprovider.ICloudEIP {
|
||||
return nil
|
||||
//return &self.EipAddress
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
|
||||
|
||||
// url, err := self.host.zone.region.GetInstanceVNCUrl(self.InstanceId)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// passwd := seclib.RandomPassword(6)
|
||||
// err = self.host.zone.region.ModifyInstanceVNCUrlPassword(self.InstanceId, passwd)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
ret := jsonutils.NewDict()
|
||||
// ret.Add(jsonutils.NewString(url), "url")
|
||||
// ret.Add(jsonutils.NewString(passwd), "password")
|
||||
// ret.Add(jsonutils.NewString("aliyun"), "protocol")
|
||||
// ret.Add(jsonutils.NewString(self.InstanceId), "instance_id")
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) StartVM(instanceId string) error {
|
||||
// status, _ := self.GetInstanceStatus(instanceId)
|
||||
// if status != InstanceStatusStopped {
|
||||
// return cloudprovider.ErrInvalidStatus
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SInstance) StartVM() error {
|
||||
// err := self.host.zone.region.StartVM(self.InstanceId)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
return cloudprovider.WaitStatus(self, models.VM_RUNNING, 5*time.Second, 180*time.Second) // 3minutes
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(isForce bool) error {
|
||||
// err := self.host.zone.region.StopVM(self.InstanceId, isForce)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
return cloudprovider.WaitStatus(self, models.VM_READY, 10*time.Second, 300*time.Second) // 5mintues
|
||||
}
|
||||
|
||||
func (self *SInstance) SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-04-01/network"
|
||||
)
|
||||
|
||||
type PublicIPAddressPropertiesFormat struct {
|
||||
PublicIPAddressVersion string
|
||||
IPAddress string
|
||||
}
|
||||
|
||||
type PublicIPAddress struct {
|
||||
ID string
|
||||
Name string
|
||||
Location string
|
||||
Properties PublicIPAddressPropertiesFormat
|
||||
}
|
||||
|
||||
type InterfaceIPConfigurationPropertiesFormat struct {
|
||||
PrivateIPAddress string
|
||||
PrivateIPAddressVersion string
|
||||
Subnet Subnet
|
||||
Primary bool
|
||||
PublicIPAddress PublicIPAddress
|
||||
}
|
||||
|
||||
type InterfaceIPConfiguration struct {
|
||||
Properties InterfaceIPConfigurationPropertiesFormat
|
||||
Name string
|
||||
ID string
|
||||
}
|
||||
|
||||
type InterfacePropertiesFormat struct {
|
||||
IPConfigurations []InterfaceIPConfiguration
|
||||
MacAddress string
|
||||
Primary bool
|
||||
}
|
||||
|
||||
type SInstanceNic struct {
|
||||
instance *SInstance
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
Location string
|
||||
Properties InterfacePropertiesFormat
|
||||
}
|
||||
|
||||
func (self *SRegion) getNetworkInterface(resourceGroup string, nicName string) (*SInstanceNic, error) {
|
||||
nic := SInstanceNic{}
|
||||
networkClient := network.NewInterfacesClientWithBaseURI(self.client.baseUrl, self.SubscriptionID)
|
||||
networkClient.Authorizer = self.client.authorizer
|
||||
if _nic, err := networkClient.Get(context.Background(), resourceGroup, nicName, ""); err != nil {
|
||||
return nil, err
|
||||
} else if err := jsonutils.Update(&nic, _nic); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
log.Infof("get nic: %s", jsonutils.Marshal(_nic).PrettyString())
|
||||
}
|
||||
return &nic, nil
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetIP() string {
|
||||
return self.Properties.IPConfigurations[0].Properties.PrivateIPAddress
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetMAC() string {
|
||||
return self.Properties.MacAddress
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
if wires, err := self.instance.host.GetIWires(); err != nil {
|
||||
log.Errorf("GetINetwork error: %v", err)
|
||||
return nil
|
||||
} else {
|
||||
for i := 0; i < len(wires); i++ {
|
||||
wire := wires[i].(*SWire)
|
||||
if net := wire.getNetworkById(self.Properties.IPConfigurations[0].Properties.Subnet.ID); net != nil {
|
||||
return net
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
)
|
||||
|
||||
// {"AvailableIpAddressCount":4091,"CidrBlock":"172.31.32.0/20","CreationTime":"2017-03-19T13:37:44Z","Description":"System created default virtual switch.","IsDefault":true,"Status":"Available","VSwitchId":"vsw-j6c3gig5ub4fmi2veyrus","VSwitchName":"","VpcId":"vpc-j6c86z3sh8ufhgsxwme0q","ZoneId":"cn-hongkong-b"}
|
||||
|
||||
const (
|
||||
VSwitchPending = "Pending"
|
||||
VSwitchAvailable = "Available"
|
||||
)
|
||||
|
||||
type SNetwork struct {
|
||||
wire *SWire
|
||||
|
||||
AvailableIpAddressCount int
|
||||
ID string
|
||||
Name string
|
||||
Properties SubnetPropertiesFormat
|
||||
|
||||
Status string
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetId() string {
|
||||
return fmt.Sprintf("%s/%s/%s", self.wire.zone.region.GetGlobalId(), self.wire.zone.region.SubscriptionID, self.Name)
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetName() string {
|
||||
if len(self.Name) > 0 {
|
||||
return self.Name
|
||||
}
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SNetwork) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetStatus() string {
|
||||
if strings.ToLower(self.Status) == "succeeded" {
|
||||
return "avaliable"
|
||||
}
|
||||
return "disabled"
|
||||
}
|
||||
|
||||
func (self *SNetwork) Delete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetGateway() string {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.Properties.AddressPrefix)
|
||||
endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255
|
||||
endIp = endIp.StepDown() // 254
|
||||
return endIp.String()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIWire() cloudprovider.ICloudWire {
|
||||
return self.wire
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIpEnd() string {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.Properties.AddressPrefix)
|
||||
endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255
|
||||
endIp = endIp.StepDown() // 254
|
||||
endIp = endIp.StepDown() // 253
|
||||
endIp = endIp.StepDown() // 252
|
||||
return endIp.String()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIpMask() int8 {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.Properties.AddressPrefix)
|
||||
return pref.MaskLen
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIpStart() string {
|
||||
pref, _ := netutils.NewIPV4Prefix(self.Properties.AddressPrefix)
|
||||
startIp := pref.Address.NetAddr(pref.MaskLen) // 0
|
||||
startIp = startIp.StepUp() // 1
|
||||
return startIp.String()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetIsPublic() bool {
|
||||
// return self.IsDefault
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetServerType() string {
|
||||
return models.SERVER_TYPE_GUEST
|
||||
}
|
||||
|
||||
func (self *SNetwork) Refresh() error {
|
||||
// log.Debugf("vsiwtch refresh %s", self.VSwitchId)
|
||||
// new, err := self.wire.zone.region.getVSwitch(self.VSwitchId)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return jsonutils.Update(self, new)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/util/azure"
|
||||
// "yunion.io/x/log"
|
||||
)
|
||||
|
||||
type SAzureProviderFactory struct {
|
||||
providerTable map[string]*SAzureProvider
|
||||
}
|
||||
|
||||
func (self *SAzureProviderFactory) GetId() string {
|
||||
return azure.CLOUD_PROVIDER_AZURE
|
||||
}
|
||||
|
||||
func (self *SAzureProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
|
||||
provider, ok := self.providerTable[providerId]
|
||||
if ok {
|
||||
err := provider.client.UpdateAccount(account, secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return provider, nil
|
||||
}
|
||||
}
|
||||
client, err := azure.NewAzureClient(providerId, providerName, account, secret, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
self.providerTable[providerId] = &SAzureProvider{client: client}
|
||||
return self.providerTable[providerId], nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
factory := SAzureProviderFactory{
|
||||
providerTable: make(map[string]*SAzureProvider),
|
||||
}
|
||||
cloudprovider.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SAzureProvider struct {
|
||||
client *azure.SAzureClient
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) IsPublicCloud() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetId() string {
|
||||
return azure.CLOUD_PROVIDER_AZURE
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetName() string {
|
||||
return azure.CLOUD_PROVIDER_AZURE_CN
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetSysInfo() (jsonutils.JSONObject, error) {
|
||||
regions := self.client.GetIRegions()
|
||||
info := jsonutils.NewDict()
|
||||
info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
|
||||
info.Add(jsonutils.NewString(azure.AZURE_API_VERSION), "api_version")
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
return self.client.GetIRegions()
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
|
||||
return self.client.GetIRegionById(id)
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
return self.client.GetIHostById(id)
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
return self.client.GetIVpcById(id)
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return self.client.GetIStorageById(id)
|
||||
}
|
||||
|
||||
func (self *SAzureProvider) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
return self.client.GetIStoragecacheById(id)
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-06-01/network"
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage"
|
||||
)
|
||||
|
||||
type VMSize struct {
|
||||
MaxDataDiskCount int32
|
||||
MemoryInMB int32
|
||||
NumberOfCores int32
|
||||
Name string
|
||||
OsDiskSizeInMB int32
|
||||
ResourceDiskSizeInMB int32
|
||||
}
|
||||
|
||||
type SRegion struct {
|
||||
client *SAzureClient
|
||||
|
||||
izones []cloudprovider.ICloudZone
|
||||
ivpcs []cloudprovider.ICloudVpc
|
||||
|
||||
storageCache *SStoragecache
|
||||
|
||||
vmSize map[string]VMSize
|
||||
ID string
|
||||
SubscriptionID string
|
||||
Name string
|
||||
DisplayName string
|
||||
Latitude string
|
||||
Longitude string
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
func (self *SRegion) Refresh() error {
|
||||
// do nothing
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) fetchVMSize() error {
|
||||
computeClient := compute.NewVirtualMachineSizesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
computeClient.Authorizer = self.client.authorizer
|
||||
if vmSizeList, err := computeClient.List(context.Background(), self.Name); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.vmSize = make(map[string]VMSize, len(*vmSizeList.Value))
|
||||
for _, _vmSize := range *vmSizeList.Value {
|
||||
vmSize := VMSize{}
|
||||
jsonutils.Update(&vmSize, _vmSize)
|
||||
self.vmSize[*_vmSize.Name] = vmSize
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getVMSize(size string) (*VMSize, error) {
|
||||
if self.vmSize == nil || len(self.vmSize) == 0 {
|
||||
if err := self.fetchVMSize(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if vmSize, ok := self.vmSize[size]; !ok {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return &vmSize, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SRegion) GetName() string {
|
||||
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_CN, self.DisplayName)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_AZURE, self.Name)
|
||||
}
|
||||
|
||||
func (self *SRegion) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SRegion) GetProvider() string {
|
||||
return CLOUD_PROVIDER_AZURE
|
||||
}
|
||||
|
||||
func (self *SRegion) GetLatitude() float32 {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (self *SRegion) GetLongitude() float32 {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (self *SRegion) GetStatus() string {
|
||||
return models.CLOUD_REGION_STATUS_INSERVER
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateIVpc(name string, desc string, cidr string) (cloudprovider.ICloudVpc, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getZoneById(id string) (*SZone, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) fetchZones() error {
|
||||
if self.izones == nil {
|
||||
self.izones = make([]cloudprovider.ICloudZone, 1)
|
||||
zone := SZone{region: self, Name: self.Name}
|
||||
self.izones[0] = &zone
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
|
||||
if self.izones == nil {
|
||||
if err := self.fetchInfrastructure(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.izones, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getStoragecache() *SStoragecache {
|
||||
if self.storageCache == nil {
|
||||
self.storageCache = &SStoragecache{region: self}
|
||||
}
|
||||
return self.storageCache
|
||||
}
|
||||
|
||||
func (self *SRegion) getStorage() ([]SStorage, error) {
|
||||
storages := make([]SStorage, 0)
|
||||
storageClient := storage.NewAccountsClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
storageClient.Authorizer = self.client.authorizer
|
||||
if storageList, err := storageClient.List(context.Background()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
for _, _storage := range *storageList.Value {
|
||||
if *_storage.Location == self.Name {
|
||||
storage := SStorage{
|
||||
StorageId: *_storage.ID,
|
||||
storageType: string(_storage.Kind),
|
||||
Name: *_storage.Name,
|
||||
Status: string(_storage.StatusOfPrimary),
|
||||
Tier: string(_storage.Sku.Tier),
|
||||
}
|
||||
storages = append(storages, storage)
|
||||
}
|
||||
}
|
||||
}
|
||||
return storages, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getVpcs() ([]SVpc, error) {
|
||||
vpcs := make([]SVpc, 0)
|
||||
networkClient := network.NewVirtualNetworksClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
|
||||
networkClient.Authorizer = self.client.authorizer
|
||||
if vpcList, err := networkClient.ListAll(context.Background()); err != nil {
|
||||
return nil, err
|
||||
} else if err := jsonutils.Update(&vpcs, vpcList.Values()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vpcs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) fetchIVpc() error {
|
||||
if vpcs, err := self.getVpcs(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.ivpcs = make([]cloudprovider.ICloudVpc, 0)
|
||||
for i := 0; i < len(vpcs); i++ {
|
||||
if vpcs[i].Location == self.Name {
|
||||
vpcs[i].region = self
|
||||
self.ivpcs = append(self.ivpcs, &vpcs[i])
|
||||
log.Infof("find region %s vpcs: %s", self.Name, jsonutils.Marshal(&vpcs[i]).PrettyString())
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
|
||||
if self.ivpcs == nil {
|
||||
if err := self.fetchInfrastructure(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.ivpcs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) fetchInfrastructure() error {
|
||||
if err := self.fetchZones(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := self.fetchIVpc(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < len(self.ivpcs); i++ {
|
||||
for j := 0; j < len(self.izones); j++ {
|
||||
zone := self.izones[j].(*SZone)
|
||||
vpc := self.ivpcs[i].(*SVpc)
|
||||
wire := SWire{zone: zone, vpc: vpc}
|
||||
zone.addWire(&wire)
|
||||
vpc.addWire(&wire)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SStorage struct {
|
||||
zone *SZone
|
||||
StorageId string
|
||||
storageType string
|
||||
Name string
|
||||
Status string
|
||||
Tier string
|
||||
}
|
||||
|
||||
func (self *SStorage) GetId() string {
|
||||
return self.StorageId
|
||||
}
|
||||
|
||||
func (self *SStorage) GetName() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.Name)
|
||||
}
|
||||
|
||||
func (self *SStorage) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s/%s", self.zone.region.GetGlobalId(), self.zone.region.client.subscriptionId, self.Name)
|
||||
}
|
||||
|
||||
func (self *SStorage) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIZone() cloudprovider.ICloudZone {
|
||||
return self.zone
|
||||
}
|
||||
|
||||
func (self *SStorage) GetEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SStorage) GetCapacityMB() int {
|
||||
return 0 // unlimited
|
||||
}
|
||||
|
||||
func (self *SStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) {
|
||||
// diskId, err := self.zone.region.createDisk(self.zone.ZoneId, self.storageType, name, sizeGb, desc)
|
||||
// if err != nil {
|
||||
// log.Errorf("createDisk fail %s", err)
|
||||
// return nil, err
|
||||
// }
|
||||
// disk, err := self.zone.region.getDisk(diskId)
|
||||
// if err != nil {
|
||||
// log.Errorf("getDisk fail %s", err)
|
||||
// return nil, err
|
||||
// }
|
||||
// disk.storage = self
|
||||
// return disk, nil
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDisk(idStr string) (cloudprovider.ICloudDisk, error) {
|
||||
// if disk, err := self.zone.region.getDisk(idStr); err != nil {
|
||||
// return nil, err
|
||||
// } else {
|
||||
// disk.storage = self
|
||||
// return disk, nil
|
||||
// }
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
if disks, err := self.zone.region.GetDisks(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
idisks := make([]cloudprovider.ICloudDisk, len(disks))
|
||||
for i := 0; i < len(disks); i += 1 {
|
||||
disks[i].storage = self
|
||||
idisks[i] = &disks[i]
|
||||
}
|
||||
return idisks, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache {
|
||||
return self.zone.region.getStoragecache()
|
||||
}
|
||||
|
||||
func (self *SStorage) GetManagerId() string {
|
||||
return self.zone.region.client.providerId
|
||||
}
|
||||
|
||||
func (self *SStorage) GetMediumType() string {
|
||||
if self.Tier == "Premium" {
|
||||
return models.DISK_TYPE_SSD
|
||||
}
|
||||
return models.DISK_TYPE_ROTATE
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStorageConf() jsonutils.JSONObject {
|
||||
conf := jsonutils.NewDict()
|
||||
return conf
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStatus() string {
|
||||
return models.STORAGE_ONLINE
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStorageType() string {
|
||||
//return models.STORAGE_PUBLIC_CLOUD
|
||||
return self.storageType
|
||||
}
|
||||
|
||||
func (self *SStorage) Refresh() error {
|
||||
// do nothing
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SStoragecache struct {
|
||||
region *SRegion
|
||||
|
||||
iimages []cloudprovider.ICloudImage
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetId() string {
|
||||
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetName() string {
|
||||
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetStatus() string {
|
||||
return "available"
|
||||
}
|
||||
|
||||
func (self *SStoragecache) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
|
||||
}
|
||||
|
||||
func (self *SStoragecache) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetManagerId() string {
|
||||
return self.region.client.providerId
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
|
||||
// if self.iimages == nil {
|
||||
// err := self.fetchImages()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
return self.iimages, nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) UploadImage(userCred mcclient.TokenCredential, imageId string, extId string, isForce bool) (string, error) {
|
||||
|
||||
return "", nil
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type AddressSpace struct {
|
||||
AddressPrefixes []string
|
||||
}
|
||||
|
||||
type SubnetPropertiesFormat struct {
|
||||
AddressPrefix string
|
||||
}
|
||||
|
||||
type Subnet struct {
|
||||
Properties SubnetPropertiesFormat
|
||||
Name string
|
||||
ID string
|
||||
}
|
||||
|
||||
type VirtualNetworkPropertiesFormat struct {
|
||||
AddressSpace AddressSpace
|
||||
Subnets []Subnet
|
||||
}
|
||||
|
||||
type SVpc struct {
|
||||
region *SRegion
|
||||
|
||||
iwires []cloudprovider.ICloudWire
|
||||
|
||||
// subnets []SSubnet
|
||||
secgroups []cloudprovider.ICloudSecurityGroup
|
||||
|
||||
// CidrBlock string
|
||||
// Description string
|
||||
IsDefault bool
|
||||
// RegionId string
|
||||
Status string
|
||||
// VpcId string
|
||||
// VpcName string
|
||||
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
Location string
|
||||
Tags map[string]string
|
||||
Properties VirtualNetworkPropertiesFormat
|
||||
}
|
||||
|
||||
func (self *SVpc) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SVpc) GetName() string {
|
||||
if len(self.Name) > 0 {
|
||||
return self.Name
|
||||
}
|
||||
return self.ID
|
||||
}
|
||||
|
||||
func (self *SVpc) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s/%s", self.region.GetGlobalId(), self.region.SubscriptionID, self.Name)
|
||||
}
|
||||
|
||||
func (self *SVpc) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIsDefault() bool {
|
||||
return self.IsDefault
|
||||
}
|
||||
|
||||
func (self *SVpc) GetCidrBlock() string {
|
||||
return self.Properties.AddressSpace.AddressPrefixes[0]
|
||||
}
|
||||
|
||||
func (self *SVpc) Delete() error {
|
||||
return nil
|
||||
//return self.region.DeleteVpc(self.VpcId)
|
||||
}
|
||||
|
||||
func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
|
||||
// if self.secgroups == nil {
|
||||
// err := self.fetchSecurityGroups()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
return self.secgroups, nil
|
||||
}
|
||||
|
||||
func (self *SVpc) fetchWires() error {
|
||||
self.iwires = make([]cloudprovider.ICloudWire, 0)
|
||||
networks := make([]cloudprovider.ICloudNetwork, len(self.Properties.Subnets))
|
||||
wire := SWire{zone: self.region.izones[0].(*SZone), vpc: self, inetworks: networks}
|
||||
for i, _network := range self.Properties.Subnets {
|
||||
network := SNetwork{wire: &wire}
|
||||
if err := jsonutils.Update(&network, _network); err != nil {
|
||||
return err
|
||||
}
|
||||
networks[i] = &network
|
||||
}
|
||||
self.iwires = append(self.iwires, &wire)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) {
|
||||
if self.iwires == nil {
|
||||
if err := self.fetchWires(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(self.iwires); i++ {
|
||||
if self.iwires[i].GetGlobalId() == wireId {
|
||||
return self.iwires[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
if self.iwires == nil {
|
||||
if err := self.fetchWires(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.iwires, nil
|
||||
}
|
||||
|
||||
func (self *SVpc) GetManagerId() string {
|
||||
return self.region.client.providerId
|
||||
}
|
||||
|
||||
func (self *SVpc) GetRegion() cloudprovider.ICloudRegion {
|
||||
return self.region
|
||||
}
|
||||
|
||||
func (self *SVpc) GetStatus() string {
|
||||
if strings.ToLower(self.Status) == "succeeded" {
|
||||
return "avaliable"
|
||||
}
|
||||
return "disabled"
|
||||
}
|
||||
|
||||
func (self *SVpc) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) addWire(wire *SWire) {
|
||||
if self.iwires == nil {
|
||||
self.iwires = make([]cloudprovider.ICloudWire, 0)
|
||||
}
|
||||
self.iwires = append(self.iwires, wire)
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SWire struct {
|
||||
zone *SZone
|
||||
vpc *SVpc
|
||||
name string
|
||||
id string
|
||||
inetworks []cloudprovider.ICloudNetwork
|
||||
}
|
||||
|
||||
func (self *SWire) GetId() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.region.GetId())
|
||||
}
|
||||
func (self *SWire) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", self.zone.region.GetGlobalId(), self.zone.region.client.subscriptionId)
|
||||
}
|
||||
|
||||
func (self *SWire) GetName() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.region.Name)
|
||||
}
|
||||
|
||||
func (self *SWire) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SWire) GetStatus() string {
|
||||
return "available"
|
||||
}
|
||||
|
||||
func (self *SWire) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SWire) CreateINetwork(name string, cidr string, desc string) (cloudprovider.ICloudNetwork, error) {
|
||||
// vswitchId, err := self.zone.region.createVSwitch(self.zone.ZoneId, self.vpc.VpcId, name, cidr, desc)
|
||||
// if err != nil {
|
||||
// log.Errorf("createVSwitch error %s", err)
|
||||
// return nil, err
|
||||
// }
|
||||
// self.inetworks = nil
|
||||
// vswitch := self.getNetworkById(vswitchId)
|
||||
// if vswitch == nil {
|
||||
// log.Errorf("cannot find vswitch after create????")
|
||||
// return nil, cloudprovider.ErrNotFound
|
||||
// }
|
||||
// return vswitch, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SWire) GetBandwidth() int {
|
||||
return 10000
|
||||
}
|
||||
|
||||
func (self *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, error) {
|
||||
networks, err := self.GetINetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(networks); i += 1 {
|
||||
if networks[i].GetGlobalId() == netid {
|
||||
return networks[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) {
|
||||
if self.inetworks == nil {
|
||||
self.inetworks = make([]cloudprovider.ICloudNetwork, len(self.vpc.Properties.Subnets))
|
||||
for i, _netwrok := range self.vpc.Properties.Subnets {
|
||||
network := SNetwork{wire: self}
|
||||
if err := jsonutils.Update(&network, _netwrok); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
self.inetworks[i] = &network
|
||||
}
|
||||
}
|
||||
return self.inetworks, nil
|
||||
}
|
||||
|
||||
func (self *SWire) GetIVpc() cloudprovider.ICloudVpc {
|
||||
return self.vpc
|
||||
}
|
||||
|
||||
func (self *SWire) GetIZone() cloudprovider.ICloudZone {
|
||||
return self.zone
|
||||
}
|
||||
|
||||
func (self *SWire) getNetworkById(networkId string) *SNetwork {
|
||||
if networks, err := self.GetINetworks(); err != nil {
|
||||
log.Errorf("getNetworkById error: %v", err)
|
||||
return nil
|
||||
} else {
|
||||
log.Debugf("search for networks %d", len(networks))
|
||||
for i := 0; i < len(networks); i++ {
|
||||
network := networks[i].(*SNetwork)
|
||||
if network.ID == networkId {
|
||||
return network
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SZone struct {
|
||||
region *SRegion
|
||||
|
||||
iwires []cloudprovider.ICloudWire
|
||||
istorages []cloudprovider.ICloudStorage
|
||||
|
||||
host *SHost
|
||||
Name string
|
||||
}
|
||||
|
||||
func (self *SZone) GetId() string {
|
||||
return self.region.client.providerId
|
||||
}
|
||||
|
||||
func (self *SZone) GetName() string {
|
||||
return self.region.GetName()
|
||||
}
|
||||
|
||||
func (self *SZone) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.region.client.subscriptionId)
|
||||
}
|
||||
|
||||
func (self *SZone) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SZone) GetStatus() string {
|
||||
return "enable"
|
||||
}
|
||||
|
||||
func (self *SZone) Refresh() error {
|
||||
// do nothing
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZone) getHost() *SHost {
|
||||
if self.host == nil {
|
||||
self.host = &SHost{zone: self}
|
||||
}
|
||||
return self.host
|
||||
}
|
||||
|
||||
func (self *SZone) GetIRegion() cloudprovider.ICloudRegion {
|
||||
return self.region
|
||||
}
|
||||
|
||||
func (self *SZone) fetchStorages() error {
|
||||
if storages, err := self.region.getStorage(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
self.istorages = make([]cloudprovider.ICloudStorage, len(storages))
|
||||
for i := 0; i < len(storages); i++ {
|
||||
storages[i].zone = self
|
||||
self.istorages[i] = &storages[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
if err := self.fetchStorages(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.istorages, nil
|
||||
}
|
||||
|
||||
func (self *SZone) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
if self.istorages == nil {
|
||||
self.fetchStorages()
|
||||
}
|
||||
for i := 0; i < len(self.istorages); i += 1 {
|
||||
if self.istorages[i].GetGlobalId() == id {
|
||||
return self.istorages[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SZone) getStorageByTier(tier string) (*SStorage, error) {
|
||||
storages, err := self.GetIStorages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(storages); i += 1 {
|
||||
storage := storages[i].(*SStorage)
|
||||
if storage.Tier == tier {
|
||||
return storage, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("No such storage %s", tier)
|
||||
}
|
||||
|
||||
func (self *SZone) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
host := self.getHost()
|
||||
if host.GetGlobalId() == id {
|
||||
return host, nil
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) {
|
||||
return []cloudprovider.ICloudHost{self.getHost()}, nil
|
||||
}
|
||||
|
||||
func (self *SZone) addWire(wire *SWire) {
|
||||
if self.iwires == nil {
|
||||
self.iwires = make([]cloudprovider.ICloudWire, 0)
|
||||
}
|
||||
self.iwires = append(self.iwires, wire)
|
||||
}
|
||||
|
||||
func (self *SZone) GetIWires() ([]cloudprovider.ICloudWire, error) {
|
||||
return self.iwires, nil
|
||||
}
|
||||
@@ -5,10 +5,12 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/session"
|
||||
"github.com/vmware/govmomi/view"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
@@ -16,10 +18,8 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"github.com/vmware/govmomi/session"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"reflect"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SManagedObject struct {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package seclib2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -39,7 +39,7 @@ func RandomPassword2(width int) string {
|
||||
}
|
||||
buf.WriteByte(ch)
|
||||
}
|
||||
if digitsCnt > 1 && letterCnt > 1 && upperCnt > 1 && puncCnt >=1 && puncCnt <= 2 {
|
||||
if digitsCnt > 1 && letterCnt > 1 && upperCnt > 1 && puncCnt >= 1 && puncCnt <= 2 {
|
||||
return buf.String()
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package structarg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type NotEnoughArgumentsError struct {
|
||||
argument Argument
|
||||
}
|
||||
|
||||
func (e *NotEnoughArgumentsError) Error() string {
|
||||
return fmt.Sprintf("Not enough arguments, missing %s", e.argument)
|
||||
}
|
||||
+1
-1
@@ -854,7 +854,7 @@ func (this *ArgumentParser) ParseArgs(args []string, ignore_unknown bool) error
|
||||
}
|
||||
}
|
||||
if err == nil && pos_idx < len(this.posArgs) {
|
||||
err = fmt.Errorf("Not enough arguments, missing %s", this.posArgs[pos_idx])
|
||||
err = &NotEnoughArgumentsError{argument: this.posArgs[pos_idx]}
|
||||
}
|
||||
if err == nil {
|
||||
err = this.Validate()
|
||||
|
||||
Reference in New Issue
Block a user