add: gcp cloud support

This commit is contained in:
Qu Xuan
2019-11-27 10:29:28 +08:00
parent 3b50982c5c
commit 1ace23cbfa
111 changed files with 7833 additions and 70 deletions
+5
View File
@@ -45,6 +45,11 @@ type CloudaccountCredentialInput struct {
AppId string //Qcloud
SecretId string //Qcloud
SecretKey string //Qcloud
ClientEmail string //Google
ProjectId string //Google
PrivateKeyId string //Google
PrivateKey string //Google
}
type CloudaccountCreateInput struct {
+2
View File
@@ -39,6 +39,7 @@ const (
CLOUD_PROVIDER_OPENSTACK = "OpenStack"
CLOUD_PROVIDER_UCLOUD = "Ucloud"
CLOUD_PROVIDER_ZSTACK = "ZStack"
CLOUD_PROVIDER_GOOGLE = "Google"
CLOUD_PROVIDER_GENERICS3 = "S3"
CLOUD_PROVIDER_CEPH = "Ceph"
@@ -82,6 +83,7 @@ var (
CLOUD_PROVIDER_OPENSTACK,
CLOUD_PROVIDER_UCLOUD,
CLOUD_PROVIDER_ZSTACK,
CLOUD_PROVIDER_GOOGLE,
}
)
+27 -14
View File
@@ -31,6 +31,7 @@ const (
CITY_HONG_KONG = "Hongkong" //香港
CITY_NING_XIA = "Ningxia" //宁夏
CITY_GUANG_ZHOU = "Guangzhou" //广州
CITY_TAI_WAN = "Taiwan" //台湾
CITY_GUI_YANG = "Guiyang" //贵阳
CITY_TAIPEI = "Taipei" //台北市
CITY_KAOHSIUNG = "Kaohsiung" //高雄市
@@ -49,6 +50,15 @@ const (
CITY_YARRALUMLA = "Yarralumla" //亚拉伦拉
CITY_MELBOURNE = "Melbourne" //墨尔本
//芬兰
CITY_FINLAND = "Finland"
//比利时
CITY_BELGIUM = "Belgium" //比利时
//瑞士
CITY_ZURICH = "Zurich" //苏黎世
// 马来西亚
CITY_KUALA_LUMPUR = "Kuala Lumpur" //吉隆坡
@@ -61,20 +71,21 @@ const (
CITY_MAHARASHTRA = "Maharashtra" //马哈拉施特拉邦
// 美国
CITY_VIRGINIA = "Virginia" //弗吉尼亚
CITY_SILICONVALLEY = "Siliconvalley" //硅谷
CITY_OHIO = "Ohio" //俄亥俄州
CITY_N_VIRGINIA = "N. Virginia" //北弗吉尼亚
CITY_N_CALIFORNIA = "N. California" //北加州
CITY_OREGON = "Oregon" //俄勒冈州
CITY_LOS_ANGELES = "Los Angeles" //洛杉矶
CITY_SAN_FRANCISCO = "San Francisco" //旧金山
CITY_UTAH = "Utah" //犹他州
CITY_WASHINGTON = "Washington" //华盛顿
CITY_TEXAS = "Texas" //德克萨斯
CITY_CHICAGO = "Chicago" //芝加哥
CITY_IOWA = "Iowa" //爱荷华
CITY_US_GOV_WEST = "us-gov-west" //???
CITY_VIRGINIA = "Virginia" //弗吉尼亚
CITY_SILICONVALLEY = "Siliconvalley" //硅谷
CITY_OHIO = "Ohio" //俄亥俄州
CITY_N_VIRGINIA = "N. Virginia" //北弗吉尼亚
CITY_N_CALIFORNIA = "N. California" //北加州
CITY_OREGON = "Oregon" //俄勒冈州
CITY_LOS_ANGELES = "Los Angeles" //洛杉矶
CITY_SAN_FRANCISCO = "San Francisco" //旧金山
CITY_UTAH = "Utah" //犹他州
CITY_WASHINGTON = "Washington" //华盛顿
CITY_TEXAS = "Texas" //德克萨斯
CITY_CHICAGO = "Chicago" //芝加哥
CITY_IOWA = "Iowa" //爱荷华
CITY_US_GOV_WEST = "us-gov-west" //???
CITY_SOUTH_CAROLINA = "South Carolina" //南卡罗来纳州
// 英国
CITY_LONDON = "London" //伦敦
@@ -95,6 +106,7 @@ const (
CITY_CANADA_CENTRAL = "Canada Central" //加拿大中部
CITY_QUEBEC = "Quebec" //魁北克市
CITY_TORONTO = "Toronto" //多伦多
CITY_MONTREAL = "Montreal" //蒙特利尔
// 爱尔兰
CITY_IRELAND = "Ireland" //爱尔兰
@@ -154,4 +166,5 @@ const (
COUNTRY_CODE_RU = "RU" //俄罗斯
COUNTRY_CODE_NG = "NG" //尼日利亚
COUNTRY_CODE_VN = "VN" //越南
COUNTRY_CODE_CH = "CH" //瑞士
)
+20
View File
@@ -0,0 +1,20 @@
// Copyright 2019 Yunion
//
// 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.
package compute
const (
GLOBAL_NETWORK_STATUS_AVAILABLE = "available"
GLOBAL_NETWORK_STATUS_UNKNOWN = "unknown"
)
+5
View File
@@ -140,6 +140,7 @@ const (
HYPERVISOR_OPENSTACK = "openstack"
HYPERVISOR_UCLOUD = "ucloud"
HYPERVISOR_ZSTACK = "zstack"
HYPERVISOR_GOOGLE = "google"
// HYPERVISOR_DEFAULT = HYPERVISOR_KVM
HYPERVISOR_DEFAULT = HYPERVISOR_KVM
@@ -161,6 +162,7 @@ var HYPERVISORS = []string{
HYPERVISOR_OPENSTACK,
HYPERVISOR_UCLOUD,
HYPERVISOR_ZSTACK,
HYPERVISOR_GOOGLE,
}
var ONECLOUD_HYPERVISORS = []string{
@@ -176,6 +178,7 @@ var PUBLIC_CLOUD_HYPERVISORS = []string{
HYPERVISOR_QCLOUD,
HYPERVISOR_HUAWEI,
HYPERVISOR_UCLOUD,
HYPERVISOR_GOOGLE,
}
var PRIVATE_CLOUD_HYPERVISORS = []string{
@@ -198,6 +201,7 @@ var HYPERVISOR_HOSTTYPE = map[string]string{
HYPERVISOR_OPENSTACK: HOST_TYPE_OPENSTACK,
HYPERVISOR_UCLOUD: HOST_TYPE_UCLOUD,
HYPERVISOR_ZSTACK: HOST_TYPE_ZSTACK,
HYPERVISOR_GOOGLE: HOST_TYPE_GOOGLE,
}
var HOSTTYPE_HYPERVISOR = map[string]string{
@@ -213,6 +217,7 @@ var HOSTTYPE_HYPERVISOR = map[string]string{
HOST_TYPE_OPENSTACK: HYPERVISOR_OPENSTACK,
HOST_TYPE_UCLOUD: HYPERVISOR_UCLOUD,
HOST_TYPE_ZSTACK: HYPERVISOR_ZSTACK,
HOST_TYPE_GOOGLE: HYPERVISOR_GOOGLE,
}
const (
+1
View File
@@ -31,6 +31,7 @@ const (
HOST_TYPE_OPENSTACK = "openstack"
HOST_TYPE_UCLOUD = "ucloud"
HOST_TYPE_ZSTACK = "zstack"
HOST_TYPE_GOOGLE = "google"
HOST_TYPE_DEFAULT = HOST_TYPE_HYPERVISOR
+1
View File
@@ -56,6 +56,7 @@ var (
REGIONAL_NETWORK_PROVIDERS = []string{
CLOUD_PROVIDER_HUAWEI,
CLOUD_PROVIDER_UCLOUD,
CLOUD_PROVIDER_GOOGLE,
}
)
+5
View File
@@ -70,6 +70,11 @@ const (
// Zstack storage type
STORAGE_ZSTACK_LOCAL_STORAGE = "localstorage"
STORAGE_ZSTACK_CEPH = "ceph"
// Google storage type
STORAGE_GOOGLE_LOCAL_STORAGE = "local-storage" //本地SSD暂存盘 (最多8个)
STORAGE_GOOGLE_PD_STANDARD = "pd-standard" //标准永久性磁盘
STORAGE_GOOGLE_PD_SSD = "pd-ssd" //SSD永久性磁盘
)
const (
+3
View File
@@ -73,6 +73,9 @@ type ICloudProvider interface {
GetIProjects() ([]ICloudProject, error)
GetIRegionById(id string) (ICloudRegion, error)
GetIGlobalnetworks() ([]ICloudGlobalnetwork, error)
GetIGlobalnetworkById(id string) (ICloudGlobalnetwork, error)
GetOnPremiseIRegion() (ICloudRegion, error)
GetBalance() (float64, string, error)
+5
View File
@@ -427,6 +427,7 @@ type ICloudVpc interface {
GetIWireById(wireId string) (ICloudWire, error)
GetINatGateways() ([]ICloudNatGateway, error)
GetIGlobalNetworkId() string
}
type ICloudWire interface {
@@ -930,3 +931,7 @@ type ICloudEvent interface {
GetCreatedAt() time.Time
}
type ICloudGlobalnetwork interface {
ICloudResource
}
+52
View File
@@ -0,0 +1,52 @@
// Copyright 2019 Yunion
//
// 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.
package guestdrivers
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SGoogleGuestDriver struct {
SManagedVirtualizedGuestDriver
}
func init() {
driver := SGoogleGuestDriver{}
models.RegisterGuestDriver(&driver)
}
func (self *SGoogleGuestDriver) GetQuotaPlatformID() []string {
return []string{
api.CLOUD_ENV_PUBLIC_CLOUD,
api.CLOUD_PROVIDER_GOOGLE,
}
}
func (self *SGoogleGuestDriver) GetHypervisor() string {
return api.HYPERVISOR_GOOGLE
}
func (self *SGoogleGuestDriver) GetProvider() string {
return api.CLOUD_PROVIDER_GOOGLE
}
func (self *SGoogleGuestDriver) GetDefaultSysDiskBackend() string {
return api.STORAGE_GOOGLE_PD_STANDARD
}
func (self *SGoogleGuestDriver) GetMinimalSysDiskSizeGb() int {
return 10
}
+8 -2
View File
@@ -301,7 +301,10 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
return errors.Wrap(err, "vpc.GetRegion")
}
vpcId := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc, false)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
secgroups := guest.GetSecgroups()
for i, secgroup := range secgroups {
@@ -910,7 +913,10 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncSecgroupsOnHost(ctx conte
region := host.GetRegion()
vpcId := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc, false)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
secgroups := guest.GetSecgroups()
externalIds := []string{}
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// 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.
package hostdrivers
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SGoogleHostDriver struct {
SManagedVirtualizationHostDriver
}
func init() {
driver := SGoogleHostDriver{}
models.RegisterHostDriver(&driver)
}
func (self *SGoogleHostDriver) GetHostType() string {
return api.HOST_TYPE_GOOGLE
}
func (self *SGoogleHostDriver) GetHypervisor() string {
return api.HYPERVISOR_GOOGLE
}
+5 -1
View File
@@ -81,7 +81,7 @@ type SCloudaccount struct {
AccessUrl string `width:"64" charset:"ascii" nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
Account string `width:"128" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"` // Column(VARCHAR(64, charset='ascii'), nullable=False)
Secret string `width:"256" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"` // Column(VARCHAR(256, charset='ascii'), nullable=False)
Secret string `length:"0" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"` // Google需要秘钥认证,需要此字段比较长
// BalanceKey string `width:"256" charset:"ascii" nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
@@ -1440,6 +1440,10 @@ func (account *SCloudaccount) syncAccountStatus(ctx context.Context, userCred mc
log.Errorf("syncCloudproviderRegion fail %s", err)
return err
}
err = providers[i].syncCloudproviderGlobalnetworks(ctx, userCred)
if err != nil {
log.Errorf("failed to sync cloudprovider globalnetwork for %s %s error: %v", providers[i].Provider, providers[i].Name, err)
}
}
}
return nil
+7 -3
View File
@@ -356,9 +356,10 @@ func (self *SCloudproviderregion) DoSync(ctx context.Context, userCred mcclient.
if localRegion.isManaged() {
remoteRegion, err := driver.GetIRegionById(localRegion.ExternalId)
if err == nil {
err = syncPublicCloudProviderInfo(ctx, userCred, syncResults, provider, driver, localRegion, remoteRegion, &syncRange)
if err != nil {
return errors.Wrap(err, "GetIRegionById")
}
err = syncPublicCloudProviderInfo(ctx, userCred, syncResults, provider, driver, localRegion, remoteRegion, &syncRange)
} else {
err = syncOnPremiseCloudProviderInfo(ctx, userCred, syncResults, provider, driver, &syncRange)
}
@@ -384,7 +385,10 @@ func (self *SCloudproviderregion) getSyncTaskKey() string {
func (self *SCloudproviderregion) submitSyncTask(userCred mcclient.TokenCredential, syncRange SSyncRange, waitChan chan bool) {
self.markStartSync(userCred)
RunSyncCloudproviderRegionTask(self.getSyncTaskKey(), func() {
self.DoSync(context.Background(), userCred, syncRange)
err := self.DoSync(context.Background(), userCred, syncRange)
if err != nil {
log.Errorf("DoSync faild %v", err)
}
if waitChan != nil {
waitChan <- true
}
+21 -1
View File
@@ -77,7 +77,7 @@ type SCloudprovider struct {
AccessUrl string `width:"64" charset:"ascii" nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
Account string `width:"128" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"` // Column(VARCHAR(64, charset='ascii'), nullable=False)
Secret string `width:"256" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"` // Column(VARCHAR(256, charset='ascii'), nullable=False)
Secret string `length:"0" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"` // Google需要秘钥认证,需要此字段比较长
CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"`
@@ -1085,6 +1085,25 @@ func (provider *SCloudprovider) markProviderConnected(ctx context.Context, userC
return provider.ClearSchedDescCache()
}
func (provider *SCloudprovider) syncCloudproviderGlobalnetworks(ctx context.Context, userCred mcclient.TokenCredential) error {
driver, err := provider.GetProvider()
if err != nil {
return err
}
if !driver.GetFactory().IsOnPremise() {
globalnetworks, err := driver.GetIGlobalnetworks()
if err != nil {
return errors.Wrap(err, "GetIGlobalnetworks")
}
result := GlobalNetworkManager.SyncGlobalnetworks(ctx, userCred, provider, globalnetworks)
if result.IsError() {
log.Errorf("syncGlobalnetworks fail %s", result.Result())
}
return nil
}
return nil
}
func (provider *SCloudprovider) prepareCloudproviderRegions(ctx context.Context, userCred mcclient.TokenCredential) ([]SCloudproviderregion, error) {
driver, err := provider.GetProvider()
if err != nil {
@@ -1181,6 +1200,7 @@ func (self *SCloudprovider) RealDelete(ctx context.Context, userCred mcclient.To
DBInstanceBackupManager,
ElasticcacheManager,
VpcManager,
GlobalNetworkManager,
ElasticipManager,
NetworkInterfaceManager,
CloudproviderRegionManager,
+233
View File
@@ -0,0 +1,233 @@
// Copyright 2019 Yunion
//
// 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.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SGlobalNetworkManager struct {
db.SEnabledStatusStandaloneResourceBaseManager
}
var GlobalNetworkManager *SGlobalNetworkManager
func init() {
GlobalNetworkManager = &SGlobalNetworkManager{
SEnabledStatusStandaloneResourceBaseManager: db.NewEnabledStatusStandaloneResourceBaseManager(
SGlobalNetwork{},
"globalnetworks_tbl",
"globalnetwork",
"globalnetworks",
),
}
GlobalNetworkManager.SetVirtualObject(GlobalNetworkManager)
}
type SGlobalNetwork struct {
db.SEnabledStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
Provider string `width:"64" charset:"ascii" list:"user"`
}
func (manager *SGlobalNetworkManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
//current not support create
return false
}
func (self *SGlobalNetwork) ValidateDeleteCondition(ctx context.Context) error {
return self.SEnabledStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
func (self *SGlobalNetwork) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
return self.SEnabledStatusStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
}
func (self *SGlobalNetwork) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
return self.SEnabledStatusStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
}
func (manager *SGlobalNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return manager.SEnabledStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
}
func (self *SGlobalNetwork) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return self.SEnabledStatusStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data)
}
func (self *SGlobalNetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
log.Infof("SGlobalNetwork delete do nothing")
self.SetStatus(userCred, api.NETWORK_STATUS_START_DELETE, "")
return nil
}
func (self *SGlobalNetwork) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
if len(self.ExternalId) > 0 {
return self.StartDeleteGlobalNetworkTask(ctx, userCred)
}
return self.RealDelete(ctx, userCred)
}
func (self *SGlobalNetwork) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(ctx), userCred)
self.SetStatus(userCred, api.NETWORK_STATUS_DELETED, "real delete")
return self.SEnabledStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SGlobalNetwork) StartDeleteGlobalNetworkTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "GlobalNetworkDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
}
func (manager *SGlobalNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
return manager.SEnabledStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
}
func (self *SGlobalNetwork) ValidateUpdateCondition(ctx context.Context) error {
return self.SEnabledStatusStandaloneResourceBase.ValidateUpdateCondition(ctx)
}
func (manager *SGlobalNetworkManager) GetGlobalNetworksByManagerId(id string) ([]SGlobalNetwork, error) {
q := manager.Query().Equals("manager_id", id)
q = q.Filter(sqlchemy.NOT(sqlchemy.IsNullOrEmpty(q.Field("external_id"))))
globalnetworks := []SGlobalNetwork{}
err := db.FetchModelObjects(manager, q, &globalnetworks)
if err != nil {
return nil, err
}
return globalnetworks, nil
}
func (self *SGlobalNetwork) GetGlobalNetworkVpcs() ([]SGlobalnetworkVpc, error) {
gnvs := []SGlobalnetworkVpc{}
q := GlobalnetworkVpcManager.Query().Equals("globalnetwork_id", self.Id)
err := db.FetchModelObjects(GlobalnetworkVpcManager, q, &gnvs)
if err != nil {
return nil, err
}
return gnvs, nil
}
func (manager *SGlobalNetworkManager) SyncGlobalnetworks(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudGlobalnetwork) compare.SyncResult {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
result := compare.SyncResult{}
dbNetworks, err := manager.GetGlobalNetworksByManagerId(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SGlobalNetwork, 0)
commondb := make([]SGlobalNetwork, 0)
commonext := make([]cloudprovider.ICloudGlobalnetwork, 0)
added := make([]cloudprovider.ICloudGlobalnetwork, 0)
err = compare.CompareSets(dbNetworks, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrap(err, "CompareSets"))
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].syncRemoveGlobalnetwork(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
// update
err = commondb[i].syncWithCloudGlobalnetwork(ctx, userCred, provider, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
err := manager.newFromCloudGlobalnetwork(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SGlobalNetwork) syncWithCloudGlobalnetwork(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudGlobalnetwork) error {
diff, err := db.UpdateWithLock(ctx, self, func() error {
self.Status = ext.GetStatus()
return nil
})
if err != nil {
return errors.Wrap(err, "UpdateWithLock")
}
db.OpsLog.LogSyncUpdate(self, diff, userCred)
return nil
}
func (self *SGlobalNetwork) syncRemoveGlobalnetwork(ctx context.Context, userCred mcclient.TokenCredential) error {
err := self.ValidateDeleteCondition(ctx)
if err != nil {
return err
}
return self.RealDelete(ctx, userCred)
}
func (manager *SGlobalNetworkManager) newFromCloudGlobalnetwork(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudGlobalnetwork) error {
network := SGlobalNetwork{}
network.SetModelManager(manager, &network)
newName, err := db.GenerateName(manager, nil, ext.GetName())
if err != nil {
return errors.Wrap(err, "GenerateName")
}
network.ExternalId = ext.GetGlobalId()
network.Name = newName
network.Status = ext.GetStatus()
network.Enabled = true
network.ManagerId = provider.Id
network.Provider = provider.Provider
err = manager.TableSpec().Insert(&network)
if err != nil {
return errors.Wrap(err, "Insert")
}
db.OpsLog.LogEvent(&network, db.ACT_CREATE, network.GetShortDesc(ctx), userCred)
return nil
}
+130
View File
@@ -0,0 +1,130 @@
// Copyright 2019 Yunion
//
// 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.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SGlobalnetworkVpcManager struct {
db.SJointResourceBaseManager
}
var GlobalnetworkVpcManager *SGlobalnetworkVpcManager
func init() {
db.InitManager(func() {
GlobalnetworkVpcManager = &SGlobalnetworkVpcManager{
SJointResourceBaseManager: db.NewJointResourceBaseManager(
SGlobalnetworkVpc{},
"globalnetworkvpcs_tbl",
"globalnetworkvpc",
"globalnetworkvpcs",
GlobalNetworkManager,
VpcManager,
),
}
GlobalnetworkVpcManager.SetVirtualObject(GlobalnetworkVpcManager)
})
}
type SGlobalnetworkVpc struct {
db.SJointResourceBase
GlobalnetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
VpcId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
}
func (manager *SGlobalnetworkVpcManager) GetMasterFieldName() string {
return "globalnetwork_id"
}
func (manager *SGlobalnetworkVpcManager) GetSlaveFieldName() string {
return "vpc_id"
}
func (joint *SGlobalnetworkVpc) Master() db.IStandaloneModel {
return db.JointMaster(joint)
}
func (joint *SGlobalnetworkVpc) Slave() db.IStandaloneModel {
return db.JointSlave(joint)
}
func (manager *SGlobalnetworkVpcManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsAdminAllowList(userCred, manager)
}
func (manager *SGlobalnetworkVpcManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowCreate(userCred, manager)
}
func (manager *SGlobalnetworkVpcManager) AllowListDescendent(ctx context.Context, userCred mcclient.TokenCredential, model db.IStandaloneModel, query jsonutils.JSONObject) bool {
return db.IsAdminAllowList(userCred, manager)
}
func (manager *SGlobalnetworkVpcManager) AllowAttach(ctx context.Context, userCred mcclient.TokenCredential, master db.IStandaloneModel, slave db.IStandaloneModel) bool {
return db.IsAdminAllowCreate(userCred, manager)
}
func (self *SGlobalnetworkVpc) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsAdminAllowGet(userCred, self)
}
func (self *SGlobalnetworkVpc) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool {
return db.IsAdminAllowUpdate(userCred, self)
}
func (self *SGlobalnetworkVpc) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowDelete(userCred, self)
}
func (self *SGlobalnetworkVpc) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
}
func (self *SGlobalnetworkVpc) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
return self.SJointResourceBase.GetCustomizeColumns(ctx, userCred, query)
}
func (self *SGlobalnetworkVpc) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
return self.SJointResourceBase.GetExtraDetails(ctx, userCred, query)
}
func (manager *SGlobalnetworkVpcManager) NewGlobalnetworkVpc(vpc *SVpc, globalnetwork *SGlobalNetwork) error {
q := manager.Query().Equals("vpc_id", vpc.Id).Equals("globalnetwork_id", globalnetwork.Id)
count, err := q.CountWithError()
if err != nil {
return errors.Wrap(err, "CountWithError")
}
if count > 1 {
return sqlchemy.ErrDuplicateEntry
}
if count == 1 {
return nil
}
gv := &SGlobalnetworkVpc{}
gv.SetModelManager(manager, gv)
gv.VpcId = vpc.Id
gv.GlobalnetworkId = globalnetwork.Id
return manager.TableSpec().Insert(gv)
}
+53
View File
@@ -1620,3 +1620,56 @@ func (manager *SSecurityGroupCacheManager) purgeAll(ctx context.Context, userCre
}
return nil
}
func (gnv *SGlobalnetworkVpc) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, gnv)
defer lockman.ReleaseObject(ctx, gnv)
return gnv.Delete(ctx, userCred)
}
func (gn *SGlobalNetwork) purgeGlobalNetworkVpcs(ctx context.Context, userCred mcclient.TokenCredential) error {
globalnetworkVpcs, err := gn.GetGlobalNetworkVpcs()
if err != nil {
return errors.Wrap(err, "gn.GetGlobalNetworkVpcs")
}
for i := range globalnetworkVpcs {
err = globalnetworkVpcs[i].purge(ctx, userCred)
if err != nil {
return errors.Wrap(err, "globalnetworkVpcs[i].purge")
}
}
return nil
}
func (gn *SGlobalNetwork) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, gn)
defer lockman.ReleaseObject(ctx, gn)
err := gn.purgeGlobalNetworkVpcs(ctx, userCred)
if err != nil {
return errors.Wrap(err, "gn.purgeGlobalNetworkVpcs")
}
err = gn.ValidateDeleteCondition(ctx)
if err != nil {
return errors.Wrapf(err, "globalnetwork %s(%s)", gn.Name, gn.Id)
}
return gn.RealDelete(ctx, userCred)
}
func (manager *SGlobalNetworkManager) purgeAll(ctx context.Context, userCred mcclient.TokenCredential, providerId string) error {
globalnetworks := []SGlobalNetwork{}
err := fetchByManagerId(manager, providerId, &globalnetworks)
if err != nil {
return err
}
for i := range globalnetworks {
err := globalnetworks[i].purge(ctx, userCred)
if err != nil {
return err
}
}
return nil
}
+2 -1
View File
@@ -117,8 +117,9 @@ type IRegionDriver interface {
RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *SVpc, secgroup *SSecurityGroup) (string, error)
IsSupportClassicSecurityGroup() bool
IsSecurityGroupBelongVpc() bool
IsSecurityGroupBelongGlobalNetwork() bool //安全组子账号范围内可用
GetDefaultSecurityGroupVpcId() string
GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, host *SHost, vpc *SVpc, classic bool) string
GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, host *SHost, vpc *SVpc, classic bool) (string, error)
ValidateCreateDBInstanceData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.SDBInstanceCreateInput, skus []SDBInstanceSku, network *SNetwork) (*api.SDBInstanceCreateInput, error)
ValidateCreateDBInstanceAccountData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, instance *SDBInstance, input *api.SDBInstanceAccountCreateInput) (*api.SDBInstanceAccountCreateInput, error)
+13 -2
View File
@@ -223,10 +223,21 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
}
vpcId := ""
if region.GetDriver().IsSecurityGroupBelongVpc() {
if region.GetDriver().IsSecurityGroupBelongGlobalNetwork() { //globalnetwork没有region属性
vpcId, err = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
if err != nil {
syncResult.Error(errors.Wrap(err, "GetSecurityGroupVpcId"))
return localSecgroups, remoteSecgroups, syncResult
}
region = nil
} else if region.GetDriver().IsSecurityGroupBelongVpc() {
vpcId = vpc.ExternalId
} else if region.GetDriver().IsSupportClassicSecurityGroup() && len(secgroups) > 0 {
vpcId = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, secgroups[0].GetVpcId() == "classic")
vpcId, err = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, secgroups[0].GetVpcId() == "classic")
if err != nil {
syncResult.Error(errors.Wrap(err, "GetSecurityGroupVpcId"))
return localSecgroups, remoteSecgroups, syncResult
}
} else {
vpcId = region.GetDriver().GetDefaultSecurityGroupVpcId()
}
+46
View File
@@ -347,6 +347,13 @@ func (manager *SVpcManager) SyncVPCs(ctx context.Context, userCred mcclient.Toke
remoteVPCs = append(remoteVPCs, commonext[i])
syncResult.Update()
}
globalnetworkId := commonext[i].GetIGlobalNetworkId()
if len(globalnetworkId) > 0 {
err := commondb[i].checkAndSetGlobalNetwork(globalnetworkId)
if err != nil {
log.Errorf("failed to set globalnetwork for %s error: %v", globalnetworkId, err)
}
}
}
for i := 0; i < len(added); i += 1 {
new, err := manager.newFromCloudVpc(ctx, userCred, added[i], provider, region)
@@ -358,6 +365,13 @@ func (manager *SVpcManager) SyncVPCs(ctx context.Context, userCred mcclient.Toke
remoteVPCs = append(remoteVPCs, added[i])
syncResult.Add()
}
globalnetworkId := added[i].GetIGlobalNetworkId()
if len(globalnetworkId) > 0 {
err := new.checkAndSetGlobalNetwork(globalnetworkId)
if err != nil {
log.Errorf("failed to set globalnetwork for %s error: %v", globalnetworkId, err)
}
}
}
return localVPCs, remoteVPCs, syncResult
@@ -400,6 +414,14 @@ func (self *SVpc) SyncWithCloudVpc(ctx context.Context, userCred mcclient.TokenC
return nil
}
func (vpc *SVpc) checkAndSetGlobalNetwork(globalnetworkId string) error {
globalnetwork, err := db.FetchByExternalId(GlobalNetworkManager, globalnetworkId)
if err != nil {
return errors.Wrap(err, "FetchByExternalId")
}
return GlobalnetworkVpcManager.NewGlobalnetworkVpc(vpc, globalnetwork.(*SGlobalNetwork))
}
func (manager *SVpcManager) newFromCloudVpc(ctx context.Context, userCred mcclient.TokenCredential, extVPC cloudprovider.ICloudVpc, provider *SCloudprovider, region *SCloudregion) (*SVpc, error) {
vpc := SVpc{}
vpc.SetModelManager(manager, &vpc)
@@ -787,3 +809,27 @@ func (vpc *SVpc) StartVpcSyncstatusTask(ctx context.Context, userCred mcclient.T
task.ScheduleRun(nil)
return nil
}
func (vpc *SVpc) GetGlobalNetwork() (*SGlobalNetwork, error) {
gv := GlobalnetworkVpcManager.Query().SubQuery()
q := GlobalNetworkManager.Query()
q.Join(gv, sqlchemy.Equals(q.Field("id"), gv.Field("globalnetwork_id")))
q = q.Filter(sqlchemy.Equals(gv.Field("vpc_id"), vpc.Id))
count, err := q.CountWithError()
if err != nil {
return nil, errors.Wrap(err, "CountWithError")
}
if count > 1 {
return nil, sqlchemy.ErrDuplicateEntry
}
if count == 0 {
return nil, sql.ErrNoRows
}
globalnetwork := &SGlobalNetwork{}
globalnetwork.SetModelManager(GlobalNetworkManager, globalnetwork)
err = q.First(globalnetwork)
if err != nil {
return nil, errors.Wrap(err, "First")
}
return globalnetwork, nil
}
+6 -2
View File
@@ -215,12 +215,16 @@ func (self *SBaseRegionDriver) IsSecurityGroupBelongVpc() bool {
return false
}
func (self *SBaseRegionDriver) IsSecurityGroupBelongGlobalNetwork() bool {
return false
}
func (self *SBaseRegionDriver) GetDefaultSecurityGroupVpcId() string {
return api.NORMAL_VPC_ID
}
func (self *SBaseRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc, classic bool) string {
return ""
func (self *SBaseRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc, classic bool) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (self *SBaseRegionDriver) RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *models.SVpc, secgroup *models.SSecurityGroup) (string, error) {
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// 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.
package regiondrivers
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SGoogleRegionDriver struct {
SManagedVirtualizationRegionDriver
}
func init() {
driver := SGoogleRegionDriver{}
models.RegisterRegionDriver(&driver)
}
func (self *SGoogleRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_GOOGLE
}
func (self *SGoogleRegionDriver) IsSecurityGroupBelongGlobalNetwork() bool {
return true
}
+19 -7
View File
@@ -1384,13 +1384,19 @@ func (self *SManagedVirtualizationRegionDriver) BindIPToNatgatewayRollback(ctx c
return nil
}
func (self *SManagedVirtualizationRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc, classic bool) string {
if region.GetDriver().IsSupportClassicSecurityGroup() && (classic || (host != nil && strings.HasSuffix(host.Name, "-classic"))) {
return "classic"
func (self *SManagedVirtualizationRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc, classic bool) (string, error) {
if region.GetDriver().IsSecurityGroupBelongGlobalNetwork() {
globalnetwork, err := vpc.GetGlobalNetwork()
if err != nil {
return "", errors.Wrap(err, "vpc.GetGlobalNetwork")
}
return globalnetwork.ExternalId, nil
} else if region.GetDriver().IsSupportClassicSecurityGroup() && (classic || (host != nil && strings.HasSuffix(host.Name, "-classic"))) {
return "classic", nil
} else if region.GetDriver().IsSecurityGroupBelongVpc() {
return vpc.ExternalId
return vpc.ExternalId, nil
}
return region.GetDriver().GetDefaultSecurityGroupVpcId()
return region.GetDriver().GetDefaultSecurityGroupVpcId(), nil
}
func (self *SManagedVirtualizationRegionDriver) RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *models.SVpc, secgroup *models.SSecurityGroup) (string, error) {
@@ -1473,7 +1479,10 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncSecurityGroup(ctx con
func (self *SManagedVirtualizationRegionDriver) RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, secgroup *models.SSecurityGroup, classic bool, task taskman.ITask) error {
vpcId := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, classic)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, classic)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
_, err := self.RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, secgroup)
return nil, err
@@ -1533,7 +1542,10 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx cont
secgroup, _ := dbinstance.GetSecgroup()
if secgroup != nil {
vpcId := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
}
desc.SecgroupId, err = region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, secgroup)
if err != nil {
return nil, errors.Wrap(err, "SyncSecurityGroup")
+2
View File
@@ -136,6 +136,7 @@ func InitHandlers(app *appsrv.Application) {
models.ElasticcacheParameterManager,
models.ElasticcacheBackupManager,
models.ElasticcacheSkuManager,
models.GlobalNetworkManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
@@ -160,6 +161,7 @@ func InitHandlers(app *appsrv.Application) {
models.NetworkinterfacenetworkManager,
models.SnapshotPolicyDiskManager,
models.InstanceSnapshotJointManager,
models.GlobalnetworkVpcManager,
} {
db.RegisterModelManager(manager)
handler := db.NewJointModelHandler(manager)
@@ -0,0 +1,35 @@
// Copyright 2019 Yunion
//
// 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.
package modules
import (
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
)
type GlobalNetworkManager struct {
modulebase.ResourceManager
}
var (
GlobalNetworks GlobalNetworkManager
)
func init() {
GlobalNetworks = GlobalNetworkManager{NewComputeManager("globalnetwork", "globalnetworks",
[]string{},
[]string{"ID", "Name", "Description"})}
registerCompute(&GlobalNetworks)
}
@@ -0,0 +1,33 @@
// Copyright 2019 Yunion
//
// 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.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
GlobalnetworkVpcs modulebase.JointResourceManager
)
func init() {
GlobalnetworkVpcs = NewJointComputeManager(
"globalnetworkvpc",
"globalnetworkvpcs",
[]string{"Globalnetwork_Id", "Globalnetwork",
"Vpc_Id", "Vpc"},
[]string{},
&GlobalNetworks,
&Vpcs)
registerCompute(&GlobalnetworkVpcs)
}
+5
View File
@@ -105,6 +105,11 @@ type SQcloudCloudAccountCreateOptions struct {
SQcloudCredential
}
type SGoogleCloudAccountCreateOptions struct {
SCloudAccountCreateBaseOptions
GoogleJsonFile string `help:"Google auth json file" positional:"true"`
}
type SAWSCloudAccountCreateOptions struct {
SCloudAccountCreateBaseOptions
SAccessKeyCredentialWithEnvironment
@@ -121,6 +121,14 @@ func (self *SAliyunProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (cli *SAliyunProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (cli *SAliyunProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SAliyunProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(extId)
}
+8
View File
@@ -114,6 +114,14 @@ func (self *SAwsProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (self *SAwsProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (self *SAwsProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SAwsProvider) GetSysInfo() (jsonutils.JSONObject, error) {
regions := self.client.GetIRegions()
info := jsonutils.NewDict()
@@ -166,6 +166,14 @@ func (self *SAzureProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (cli *SAzureProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (cli *SAzureProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SAzureProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(id)
}
+8
View File
@@ -166,6 +166,14 @@ func (self *SESXiProvider) GetIRegions() []cloudprovider.ICloudRegion {
return nil
}
func (cli *SESXiProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (cli *SESXiProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SESXiProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
return nil, cloudprovider.ErrNotSupported
}
+228
View File
@@ -0,0 +1,228 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"context"
"fmt"
"time"
"yunion.io/x/jsonutils"
billing "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SDisk struct {
storage *SStorage
Id string
CreationTimestamp time.Time
Name string
SizeGB int
Zone string
Status string
SelfLink string
Type string
SourceImage string
LastAttachTimestamp time.Time
LastDetachTimestamp time.Time
LabelFingerprint string
PhysicalBlockSizeBytes string
ResourcePolicies []string
Kind string
autoDelete bool
boot bool
index int
}
func (region *SRegion) GetDisks(zone string, storageType string, maxResults int, pageToken string) ([]SDisk, error) {
disks := []SDisk{}
if len(zone) == 0 {
return nil, fmt.Errorf("zone params can not be empty")
}
params := map[string]string{}
if len(storageType) > 0 {
params["filter"] = fmt.Sprintf(`type="%s/zones/%s/diskTypes/%s"`, region.GetUrlPrefixWithProjectId(), zone, storageType)
}
return disks, region.List(fmt.Sprintf("zones/%s/disks", zone), params, maxResults, pageToken, &disks)
}
func (region *SRegion) GetDisk(id string) (*SDisk, error) {
disk := &SDisk{}
return disk, region.Get(id, disk)
}
func (disk *SDisk) GetId() string {
return disk.SelfLink
}
func (disk *SDisk) GetGlobalId() string {
return getGlobalId(disk.SelfLink)
}
func (disk *SDisk) GetName() string {
return disk.Name
}
func (disk *SDisk) GetStatus() string {
switch disk.Status {
case "READY":
return api.DISK_READY
case "CREATING":
return api.DISK_ALLOCATING
case "RESTORING":
return api.DISK_RESET
case "FAILED":
return api.DISK_ALLOC_FAILED
case "DELETING":
return api.DISK_DEALLOC
default:
return api.DISK_UNKNOWN
}
}
func (disk *SDisk) IsEmulated() bool {
return false
}
func (disk *SDisk) Refresh() error {
_disk, err := disk.storage.zone.region.GetDisk(disk.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(disk, _disk)
}
func (disk *SDisk) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (disk *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
return disk.storage, nil
}
func (disk *SDisk) GetIStorageId() string {
return disk.storage.GetGlobalId()
}
func (disk *SDisk) GetDiskFormat() string {
return ""
}
func (disk *SDisk) GetDiskSizeMB() int {
return disk.SizeGB * 1024
}
func (disk *SDisk) GetIsAutoDelete() bool {
return disk.autoDelete
}
func (disk *SDisk) GetTemplateId() string {
return disk.SourceImage
}
func (disk *SDisk) GetDiskType() string {
if disk.index == 0 || disk.boot {
return api.DISK_TYPE_SYS
}
return api.DISK_TYPE_DATA
}
func (disk *SDisk) GetFsFormat() string {
return ""
}
func (disk *SDisk) GetIsNonPersistent() bool {
return false
}
func (disk *SDisk) GetDriver() string {
return "scsi"
}
func (disk *SDisk) GetCacheMode() string {
return "none"
}
func (disk *SDisk) GetMountpoint() string {
return ""
}
func (disk *SDisk) GetAccessPath() string {
return ""
}
func (disk *SDisk) Delete(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
}
func (disk *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (disk *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
snapshots, err := disk.storage.zone.region.GetSnapshots(disk.SelfLink, 0, "")
if err != nil {
return nil, err
}
isnapshots := []cloudprovider.ICloudSnapshot{}
for i := range snapshots {
snapshots[i].region = disk.storage.zone.region
isnapshots = append(isnapshots, &snapshots[i])
}
return isnapshots, nil
}
func (disk *SDisk) GetISnapshot(id string) (cloudprovider.ICloudSnapshot, error) {
return disk.storage.zone.region.GetSnapshot(id)
}
func (disk *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
result := []string{}
for _, policy := range disk.ResourcePolicies {
result = append(result, getGlobalId(policy))
}
return result, nil
}
func (disk *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return cloudprovider.ErrNotImplemented
}
func (disk *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (disk *SDisk) Rebuild(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
}
func (disk *SDisk) GetBillingType() string {
return billing.BILLING_TYPE_POSTPAID
}
func (disk *SDisk) GetCreatedAt() time.Time {
return disk.CreationTimestamp
}
func (disk *SDisk) GetExpiredAt() time.Time {
return time.Time{}
}
func (disk *SDisk) GetProjectId() string {
return disk.storage.zone.region.GetProjectId()
}
+1
View File
@@ -0,0 +1 @@
package google // import "yunion.io/x/onecloud/pkg/multicloud/google"
+173
View File
@@ -0,0 +1,173 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
billing "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SAddress struct {
region *SRegion
Id string
CreationTimestamp time.Time
Name string
Description string
Address string
Status string
Region string
Users []string
SelfLink string
NetworkTier string
AddressType string
Kind string
}
func (region *SRegion) GetEips(address string, maxResults int, pageToken string) ([]SAddress, error) {
eips := []SAddress{}
params := map[string]string{}
if len(address) > 0 {
params["filter"] = fmt.Sprintf(`address="%s"`, address)
}
resource := fmt.Sprintf("regions/%s/addresses", region.Name)
return eips, region.List(resource, params, maxResults, pageToken, &eips)
}
func (region *SRegion) GetEip(id string) (*SAddress, error) {
eip := &SAddress{region: region}
return eip, region.Get(id, eip)
}
func (addr *SAddress) GetId() string {
return addr.SelfLink
}
func (addr *SAddress) GetName() string {
return addr.Name
}
func (addr *SAddress) GetGlobalId() string {
return getGlobalId(addr.SelfLink)
}
func (addr *SAddress) GetStatus() string {
switch addr.Status {
case "RESERVING":
return api.EIP_STATUS_ASSOCIATE
case "RESERVED":
return api.EIP_STATUS_READY
case "IN_USE":
return api.EIP_STATUS_READY
default:
log.Errorf("Unknown eip status: %s", addr.Status)
return api.EIP_STATUS_UNKNOWN
}
}
func (addr *SAddress) GetProjectId() string {
return addr.region.GetProjectId()
}
func (addr *SAddress) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (addr *SAddress) IsEmulated() bool {
if addr.Id == addr.SelfLink {
return true
}
return false
}
func (addr *SAddress) GetCreatedAt() time.Time {
return addr.CreationTimestamp
}
func (addr *SAddress) GetExpiredAt() time.Time {
return time.Time{}
}
func (addr *SAddress) GetBillingType() string {
return billing.BILLING_TYPE_POSTPAID
}
func (addr *SAddress) Refresh() error {
if addr.IsEmulated() {
return nil
}
_addr, err := addr.region.GetEip(addr.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(addr, _addr)
}
func (addr *SAddress) GetIpAddr() string {
return addr.Address
}
func (addr *SAddress) GetMode() string {
if addr.IsEmulated() {
return api.EIP_MODE_INSTANCE_PUBLICIP
}
return api.EIP_MODE_STANDALONE_EIP
}
func (addr *SAddress) GetINetworkId() string {
return ""
}
func (addr *SAddress) GetAssociationType() string {
return api.EIP_ASSOCIATE_TYPE_SERVER
}
func (addr *SAddress) GetAssociationExternalId() string {
if len(addr.Users) > 0 {
return getGlobalId(addr.Users[0])
}
return ""
}
func (addr *SAddress) GetBandwidth() int {
return 0
}
func (addr *SAddress) GetInternetChargeType() string {
return api.EIP_CHARGE_TYPE_BY_TRAFFIC
}
func (addr *SAddress) Delete() error {
return cloudprovider.ErrNotImplemented
}
func (addr *SAddress) Associate(instanceId string) error {
return cloudprovider.ErrNotImplemented
}
func (addr *SAddress) Dissociate() error {
return cloudprovider.ErrNotImplemented
}
func (addr *SAddress) ChangeBandwidth(bw int) error {
return cloudprovider.ErrNotImplemented
}
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
)
type SGlobalNetwork struct {
Id string
//CreationTimestamp time.Time
Name string
Description string
SelfLink string
AutoCreateSubnetworks bool
Subnetworks []string
RoutingConfig map[string]string
Kind string
}
func (cli *SGoogleClient) GetGlobalNetwork(id string) (*SGlobalNetwork, error) {
net := &SGlobalNetwork{}
return net, cli.get(id, net)
}
func (cli *SGoogleClient) GetGlobalNetworks(maxResults int, pageToken string) ([]SGlobalNetwork, error) {
networks := []SGlobalNetwork{}
params := map[string]string{}
resource := "global/networks"
return networks, cli.list(resource, params, maxResults, pageToken, &networks)
}
func (net *SGlobalNetwork) GetId() string {
return net.SelfLink
}
func (net *SGlobalNetwork) GetGlobalId() string {
return getGlobalId(net.SelfLink)
}
func (net *SGlobalNetwork) GetName() string {
return net.Name
}
func (net *SGlobalNetwork) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (net *SGlobalNetwork) GetStatus() string {
return api.GLOBAL_NETWORK_STATUS_AVAILABLE
}
func (net *SGlobalNetwork) IsEmulated() bool {
return false
}
func (net *SGlobalNetwork) Refresh() error {
return nil
}
+318
View File
@@ -0,0 +1,318 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/httputils"
)
const (
CLOUD_PROVIDER_GOOGLE = api.CLOUD_PROVIDER_GOOGLE
CLOUD_PROVIDER_GOOGLE_CN = "谷歌云"
GOOGLE_DEFAULT_REGION = "asia-east1"
GOOGLE_API_VERSION = "v1"
)
type SGoogleClient struct {
providerId string
providerName string
projectId string
privateKey string
privateKeyId string
clientEmail string
iregions []cloudprovider.ICloudRegion
images []SImage
snapshots map[string][]SSnapshot
globalnetworks []SGlobalNetwork
resourcepolices []SResourcePolicy
client *http.Client
Debug bool
}
func NewGoogleClient(providerId string, providerName string, projectId, clientEmail, privateKeyId, privateKey string, isDebug bool) (*SGoogleClient, error) {
client := SGoogleClient{
providerId: providerId,
providerName: providerName,
projectId: projectId,
privateKey: strings.Replace(privateKey, "\\n", "\n", -1),
privateKeyId: privateKeyId,
clientEmail: clientEmail,
Debug: isDebug,
}
conf := &jwt.Config{
Email: clientEmail,
PrivateKeyID: privateKeyId,
PrivateKey: []byte(client.privateKey),
Scopes: []string{
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/compute.readonly",
"https://www.googleapis.com/auth/cloud-platform.read-only",
"https://www.googleapis.com/auth/cloudplatformprojects",
"https://www.googleapis.com/auth/cloudplatformprojects.readonly",
},
TokenURL: google.JWTTokenURL,
}
client.client = conf.Client(oauth2.NoContext)
return &client, client.fetchRegions()
}
func (self *SGoogleClient) GetAccountId() string {
return self.clientEmail
}
func (self *SGoogleClient) fetchRegions() error {
regions := []SRegion{}
err := self.listAll("regions", nil, &regions)
if err != nil {
return err
}
self.iregions = []cloudprovider.ICloudRegion{}
for i := 0; i < len(regions); i++ {
regions[i].client = self
self.iregions = append(self.iregions, &regions[i])
}
return nil
}
func (self *SGoogleClient) get(id string, retval interface{}) error {
if !strings.HasPrefix(id, getUrlPrefix()) {
id = getUrlPrefix() + id
}
data, err := jsonRequest(self.client, "GET", id, nil, self.Debug)
if err != nil {
if strings.Index(err.Error(), "not found") > 0 {
return cloudprovider.ErrNotFound
}
return errors.Wrap(err, "JSONRequest")
}
err = data.Unmarshal(retval)
if err != nil {
return errors.Wrap(err, "Unmarshal")
}
return nil
}
func (self *SGoogleClient) listAll(resource string, params map[string]string, retval interface{}) error {
var (
items *jsonutils.JSONArray = jsonutils.NewArray()
_items []jsonutils.JSONObject = []jsonutils.JSONObject{}
maxResults int = 500
nextPageToken string = ""
err error = nil
)
for {
_items, nextPageToken, err = self._listAll(resource, params, maxResults, nextPageToken)
if err != nil {
return errors.Wrapf(err, `_listAll("%s")`, resource)
}
items.Add(_items...)
if len(nextPageToken) == 0 || len(_items) == 0 {
break
}
}
return items.Unmarshal(retval)
}
func (self *SGoogleClient) _listAll(resource string, params map[string]string, maxResults int, pageToken string) ([]jsonutils.JSONObject, string, error) {
if params == nil {
params = map[string]string{}
}
params["maxResults"] = fmt.Sprintf("%d", maxResults)
params["pageToken"] = pageToken
data, err := self._list(resource, params)
if err != nil {
return nil, "", err
}
items := []jsonutils.JSONObject{}
if data.Contains("items") {
items, err = data.GetArray("items")
if err != nil {
return nil, "", errors.Wrap(err, "data.GetArray")
}
}
nextPageToken, _ := data.GetString("nextPageToken")
return items, nextPageToken, nil
}
func (self *SGoogleClient) list(resource string, params map[string]string, maxResults int, pageToken string, retval interface{}) error {
if maxResults == 0 && len(pageToken) == 0 {
return self.listAll(resource, params, retval)
}
params["maxResults"] = fmt.Sprintf("%d", maxResults)
params["pageToken"] = pageToken
data, err := self._list(resource, params)
if err != nil {
return errors.Wrapf(err, "_list(%s)", resource)
}
if data.Contains("items") {
err := data.Unmarshal(retval, "items")
if err != nil {
return errors.Wrap(err, "data.Unmarshal")
}
}
return nil
}
func jsonRequest(client *http.Client, method httputils.THttpMethod, url string, body jsonutils.JSONObject, debug bool) (jsonutils.JSONObject, error) {
_, data, err := httputils.JSONRequest(client, context.Background(), method, url, nil, body, debug)
if err != nil {
if strings.Index(err.Error(), "not found") > 0 {
return nil, cloudprovider.ErrNotFound
}
return nil, errors.Wrap(err, "JSONRequest")
}
return data, nil
}
func (self *SGoogleClient) _list(resource string, params map[string]string) (jsonutils.JSONObject, error) {
baseUrl := fmt.Sprintf("%s%s/%s", getUrlPrefix(), self.projectId, resource)
values := url.Values{}
for k, v := range params {
values.Set(k, v)
}
if len(values) > 0 {
baseUrl = fmt.Sprintf("%s?%s", baseUrl, values.Encode())
}
return jsonRequest(self.client, "GET", baseUrl, nil, self.Debug)
}
func (self *SGoogleClient) GetRegion(regionId string) *SRegion {
if len(regionId) == 0 {
regionId = GOOGLE_DEFAULT_REGION
}
for i := 0; i < len(self.iregions); i++ {
if self.iregions[i].GetId() == regionId {
return self.iregions[i].(*SRegion)
}
}
return nil
}
func (client *SGoogleClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
projects, err := client.GetProjects()
if err != nil {
return nil, errors.Wrap(err, "GetProjects")
}
accounts := []cloudprovider.SSubAccount{}
for _, project := range projects {
subAccount := cloudprovider.SSubAccount{}
subAccount.Name = client.providerName
subAccount.Account = fmt.Sprintf("%s/%s", project.ProjectId, client.clientEmail)
if project.LifecycleState == "ACTIVE" {
subAccount.HealthStatus = api.CLOUD_PROVIDER_HEALTH_NORMAL
} else {
subAccount.HealthStatus = api.CLOUD_PROVIDER_HEALTH_ARREARS
}
accounts = append(accounts, subAccount)
}
return accounts, nil
}
func (self *SGoogleClient) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
for i := 0; i < len(self.iregions); i++ {
if self.iregions[i].GetGlobalId() == id {
return self.iregions[i].(*SRegion), nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (self *SGoogleClient) GetIRegions() []cloudprovider.ICloudRegion {
return self.iregions
}
func (self *SGoogleClient) fetchGlobalNetwork() ([]SGlobalNetwork, error) {
if len(self.globalnetworks) > 0 {
return self.globalnetworks, nil
}
globalnetworks, err := self.GetGlobalNetworks(0, "")
if err != nil {
return nil, err
}
self.globalnetworks = globalnetworks
return globalnetworks, nil
}
func (cli *SGoogleClient) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
networks, err := cli.fetchGlobalNetwork()
if err != nil {
return nil, errors.Wrap(err, "fetchGlobalNetwork")
}
inetworks := []cloudprovider.ICloudGlobalnetwork{}
for i := range networks {
inetworks = append(inetworks, &networks[i])
}
return inetworks, nil
}
func (cli *SGoogleClient) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
network, err := cli.GetGlobalNetwork(id)
if err != nil {
return nil, err
}
return network, nil
}
func (self *SGoogleClient) GetRegions() []SRegion {
regions := make([]SRegion, len(self.iregions))
for i := 0; i < len(regions); i++ {
region := self.iregions[i].(*SRegion)
regions[i] = *region
}
return regions
}
func (self *SGoogleClient) GetIProjects() ([]cloudprovider.ICloudProject, error) {
projects, err := self.GetProjects()
if err != nil {
return nil, err
}
iprojects := []cloudprovider.ICloudProject{}
for i := range projects {
iprojects = append(iprojects, &projects[i])
}
return iprojects, nil
}
func getUrlPrefix() string {
return fmt.Sprintf("https://www.googleapis.com/compute/%s/projects/", GOOGLE_API_VERSION)
}
func getGlobalId(id string) string {
return strings.TrimPrefix(id, getUrlPrefix())
}
+187
View File
@@ -0,0 +1,187 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SHost struct {
multicloud.SHostBase
zone *SZone
}
func (self *SHost) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (host *SHost) GetId() string {
return getGlobalId(host.zone.GetId())
}
func (host *SHost) GetGlobalId() string {
return host.GetId()
}
func (host *SHost) GetName() string {
return fmt.Sprintf("%s-%s", host.zone.region.client.providerName, host.zone.GetName())
}
func (host *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
return host.zone.GetIStorages()
}
func (host *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
return host.zone.GetIStorageById(id)
}
func (host *SHost) IsEmulated() bool {
return false
}
func (host *SHost) GetStatus() string {
return api.HOST_STATUS_RUNNING
}
func (host *SHost) Refresh() error {
return nil
}
func (host *SHost) GetHostStatus() string {
return api.HOST_ONLINE
}
func (host *SHost) GetEnabled() bool {
return true
}
func (host *SHost) GetAccessIp() string {
return ""
}
func (host *SHost) GetAccessMac() string {
return ""
}
func (host *SHost) GetSysInfo() jsonutils.JSONObject {
info := jsonutils.NewDict()
info.Add(jsonutils.NewString(CLOUD_PROVIDER_GOOGLE), "manufacture")
return info
}
func (host *SHost) GetSN() string {
return ""
}
func (host *SHost) GetCpuCount() int {
return 0
}
func (host *SHost) GetNodeCount() int8 {
return 0
}
func (host *SHost) GetCpuDesc() string {
return ""
}
func (host *SHost) GetCpuMhz() int {
return 0
}
func (host *SHost) GetMemSizeMB() int {
return 0
}
func (host *SHost) GetStorageSizeMB() int {
return 0
}
func (host *SHost) GetStorageType() string {
return api.DISK_TYPE_HYBRID
}
func (host *SHost) GetHostType() string {
return api.HOST_TYPE_GOOGLE
}
func (host *SHost) GetWire() *SWire {
vpc := &SVpc{region: host.zone.region}
return &SWire{vpc: vpc}
}
func (host *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) {
ivpcs, err := host.zone.region.GetIVpcs()
if err != nil {
return nil, errors.Wrap(err, "region.GetIVpcs")
}
iwires := []cloudprovider.ICloudWire{}
for i := range ivpcs {
_iwires, err := ivpcs[i].GetIWires()
if err != nil {
return nil, errors.Wrap(err, "ivpcs[i].GetIWires")
}
iwires = append(iwires, _iwires...)
}
return iwires, nil
}
func (host *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
instances, err := host.zone.region.GetInstances(host.zone.Name, 0, "")
if err != nil {
return nil, err
}
iVMs := []cloudprovider.ICloudVM{}
for i := range instances {
instances[i].host = host
iVMs = append(iVMs, &instances[i])
}
return iVMs, nil
}
func (host *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
instance, err := host.zone.region.GetInstance(id)
if err != nil {
return nil, err
}
if instance.Zone != host.zone.SelfLink {
return nil, cloudprovider.ErrNotFound
}
return instance, nil
}
func (host *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) {
return nil, cloudprovider.ErrNotSupported
}
func (host *SHost) GetIsMaintenance() bool {
return false
}
func (host *SHost) GetVersion() string {
return GOOGLE_API_VERSION
}
+228
View File
@@ -0,0 +1,228 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"context"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/imagetools"
)
type GuestOsFeature struct {
Type string
}
type SDeprecated struct {
State string
Replacement string
Deprecated bool
}
type SImage struct {
storagecache *SStoragecache
Id string
CreationTimestamp time.Time
Name string
Description string
SourceType string
RawDisk map[string]string
Deprecated SDeprecated
Status string
ArchiveSizeBytes int64
DiskSizeGb int
Licenses []string
Family string
SelfLink string
LabelFingerprint string
GuestOsFeatures []GuestOsFeature
LicenseCodes []string
StorageLocations []string
Kind string
}
func (region *SRegion) SetProjectId(id string) {
region.client.projectId = id
}
func (region *SRegion) GetAllAvailableImages() ([]SImage, error) {
images := []SImage{}
projectId := region.client.projectId
for _, project := range []string{
"centos-cloud",
"ubuntu-os-cloud",
"windows-cloud",
"windows-sql-cloud",
"suse-cloud",
"suse-sap-cloud",
"rhel-cloud",
"rhel-sap-cloud",
"cos-cloud",
"coreos-cloud",
"debian-cloud",
projectId,
} {
_images, err := region.GetImages(project, 0, "")
if err != nil {
return nil, err
}
for _, image := range _images {
if image.Deprecated.State == "" {
images = append(images, image)
}
}
}
return images, nil
}
func (region *SRegion) GetImages(project string, maxResults int, pageToken string) ([]SImage, error) {
images := []SImage{}
resource := "global/images"
params := map[string]string{}
if len(project) > 0 {
region.SetProjectId(project)
}
return images, region.List(resource, params, maxResults, pageToken, &images)
}
func (region *SRegion) GetImage(id string) (*SImage, error) {
image := &SImage{}
return image, region.Get(id, image)
}
func (image *SImage) GetId() string {
return image.SelfLink
}
func (image *SImage) GetGlobalId() string {
return getGlobalId(image.SelfLink)
}
func (image *SImage) GetName() string {
return image.Name
}
func (image *SImage) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (image *SImage) GetMinRamSizeMb() int {
return 0
}
func (image *SImage) GetStatus() string {
switch image.Status {
case "READY":
return api.CACHED_IMAGE_STATUS_READY
case "FAILED":
return api.CACHED_IMAGE_STATUS_CACHE_FAILED
case "PENDING":
return api.CACHED_IMAGE_STATUS_SAVING
default:
log.Errorf("Unknown image status: %s", image.Status)
return api.CACHED_IMAGE_STATUS_CACHE_FAILED
}
}
func (image *SImage) GetImageStatus() string {
switch image.Status {
case "READY":
return cloudprovider.IMAGE_STATUS_ACTIVE
case "FAILED":
return cloudprovider.IMAGE_STATUS_KILLED
case "PENDING":
return cloudprovider.IMAGE_STATUS_QUEUED
default:
return cloudprovider.IMAGE_STATUS_KILLED
}
}
func (image *SImage) Refresh() error {
_image, err := image.storagecache.region.GetImage(image.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(image, _image)
}
func (image *SImage) GetImageType() string {
if strings.Index(image.SelfLink, image.storagecache.region.GetProjectId()) >= 0 {
return cloudprovider.CachedImageTypeCustomized
}
return cloudprovider.CachedImageTypeSystem
}
func (image *SImage) GetSizeByte() int64 {
return image.ArchiveSizeBytes
}
func (image *SImage) GetOsType() string {
return imagetools.NormalizeImageInfo(image.Name, "", "", "", "").OsType
}
func (image *SImage) GetOsDist() string {
return imagetools.NormalizeImageInfo(image.Name, "", "", "", "").OsDistro
}
func (image *SImage) GetOsVersion() string {
return imagetools.NormalizeImageInfo(image.Name, "", "", "", "").OsVersion
}
func (image *SImage) GetOsArch() string {
return imagetools.NormalizeImageInfo(image.Name, "", "", "", "").OsArch
}
func (image *SImage) GetMinOsDiskSizeGb() int {
return image.DiskSizeGb
}
func (image *SImage) GetCreatedAt() time.Time {
return image.CreationTimestamp
}
func (image *SImage) GetImageFormat() string {
return "vhd"
}
func (image *SImage) IsEmulated() bool {
return false
}
func (image *SImage) Delete(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
}
func (image *SImage) GetIStoragecache() cloudprovider.ICloudStoragecache {
return image.storagecache
}
func (region *SRegion) fetchImages() ([]SImage, error) {
if len(region.client.images) > 0 {
return region.client.images, nil
}
images, err := region.GetAllAvailableImages()
if err != nil {
return nil, err
}
region.client.images = images
return images, nil
}
+409
View File
@@ -0,0 +1,409 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/osprofile"
"yunion.io/x/pkg/utils"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/imagetools"
)
type AccessConfig struct {
Type string
Name string
NatIP string
NetworkTier string
Kind string
}
type InstanceDisk struct {
Type string
Mode string
Source string
DeviceName string
Index int
Boot bool
AutoDelete bool
Licenses []string
Interface string
GuestOsFeatures []GuestOsFeature
Kind string
}
type ServiceAccount struct {
Email string
scopes []string
}
type SInstanceTag struct {
Items []string
Fingerprint string
}
type SInstance struct {
multicloud.SInstanceBase
host *SHost
Id string
CreationTimestamp time.Time
Name string
Description string
Tags SInstanceTag
MachineType string
Status string
Zone string
CanIpForward bool
NetworkInterfaces []SNetworkInterface
Disks []InstanceDisk
Metadata map[string]string
ServiceAccounts []ServiceAccount
SelfLink string
Scheduling map[string]interface{}
CpuPlatform string
LabelFingerprint string
StartRestricted bool
DeletionProtection bool
Kind string
guestCpus int
memoryMb int
machineType string
}
func (region *SRegion) GetInstances(zone string, maxResults int, pageToken string) ([]SInstance, error) {
instances := []SInstance{}
params := map[string]string{}
if len(zone) == 0 {
return nil, fmt.Errorf("zone params can not be empty")
}
resource := fmt.Sprintf("zones/%s/instances", zone)
return instances, region.List(resource, params, maxResults, pageToken, &instances)
}
func (region *SRegion) GetInstance(id string) (*SInstance, error) {
instance := &SInstance{}
return instance, region.Get(id, instance)
}
func (instance *SInstance) GetId() string {
return instance.SelfLink
}
func (instnace *SInstance) GetGlobalId() string {
return getGlobalId(instnace.SelfLink)
}
func (instance *SInstance) GetName() string {
return instance.Name
}
func (instnace *SInstance) IsEmulated() bool {
return false
}
func (instance *SInstance) fetchMachineType() error {
if instance.guestCpus > 0 || instance.memoryMb > 0 || len(instance.machineType) > 0 {
return nil
}
machinetype, err := instance.host.zone.region.GetMachineType(instance.MachineType)
if err != nil {
return err
}
instance.guestCpus = machinetype.GuestCpus
instance.memoryMb = machinetype.MemoryMb
instance.machineType = machinetype.Name
return nil
}
func (instance *SInstance) Refresh() error {
_instance, err := instance.host.zone.region.GetInstance(instance.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(instance, _instance)
}
//PROVISIONING, STAGING, RUNNING, STOPPING, STOPPED, SUSPENDING, SUSPENDED, and TERMINATED.
func (instance *SInstance) GetStatus() string {
switch instance.Status {
case "PROVISIONING":
return api.VM_DEPLOYING
case "STAGING":
return api.VM_STARTING
case "RUNNING":
return api.VM_RUNNING
case "STOPPING":
return api.VM_STOPPING
case "STOPPED":
return api.VM_READY
case "SUSPENDING":
return api.VM_SUSPENDING
case "SUSPENDED":
return api.VM_SUSPEND
case "TERMINATED":
return api.VM_DELETING
default:
return api.VM_UNKNOWN
}
}
func (instance *SInstance) GetBillingType() string {
return billing_api.BILLING_TYPE_POSTPAID
}
func (instance *SInstance) GetCreatedAt() time.Time {
return instance.CreationTimestamp
}
func (instance *SInstance) GetExpiredAt() time.Time {
return time.Time{}
}
func (instance *SInstance) GetProjectId() string {
return instance.host.zone.region.GetProjectId()
}
func (instance *SInstance) GetIHost() cloudprovider.ICloudHost {
return instance.host
}
func (instance *SInstance) GetIHostId() string {
return instance.host.GetGlobalId()
}
func (instance *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
idisks := []cloudprovider.ICloudDisk{}
for _, disk := range instance.Disks {
disk, err := instance.host.zone.region.GetDisk(disk.Source)
if err != nil {
return nil, errors.Wrap(err, "GetDisk")
}
storage, err := instance.host.zone.region.GetStorage(disk.Type)
if err != nil {
return nil, errors.Wrap(err, "GetStorage")
}
storage.zone = instance.host.zone
disk.storage = storage
idisks = append(idisks, disk)
}
return idisks, nil
}
func (instance *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
nics := []cloudprovider.ICloudNic{}
for i := range instance.NetworkInterfaces {
instance.NetworkInterfaces[i].instance = instance
nics = append(nics, &instance.NetworkInterfaces[i])
}
return nics, nil
}
func (instance *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
for _, networkinterface := range instance.NetworkInterfaces {
for _, conf := range networkinterface.AccessConfigs {
if len(conf.NatIP) > 0 {
eips, err := instance.host.zone.region.GetEips(conf.NatIP, 0, "")
if err != nil {
return nil, errors.Wrapf(err, "region.GetEip(%s)", conf.NatIP)
}
if len(eips) == 1 {
return &eips[0], nil
}
eip := &SAddress{
region: instance.host.zone.region,
SelfLink: instance.SelfLink,
Id: instance.SelfLink,
Address: conf.NatIP,
}
return eip, nil
}
}
}
return nil, nil
}
func (instance *SInstance) GetVcpuCount() int {
instance.fetchMachineType()
return instance.guestCpus
}
func (instance *SInstance) GetVmemSizeMB() int {
instance.fetchMachineType()
return instance.memoryMb
}
func (instance *SInstance) GetBootOrder() string {
return "cdn"
}
func (instance *SInstance) GetVga() string {
return "std"
}
func (instance *SInstance) GetVdi() string {
return "vnc"
}
func (instance *SInstance) GetOSType() string {
for _, disk := range instance.Disks {
if disk.Index == 0 {
for _, license := range disk.Licenses {
if strings.Index(strings.ToLower(license), "windows") < 0 {
return osprofile.OS_TYPE_LINUX
} else {
return osprofile.OS_TYPE_WINDOWS
}
}
}
}
return osprofile.OS_TYPE_LINUX
}
func (instance *SInstance) GetOSName() string {
for _, disk := range instance.Disks {
if disk.Index == 0 {
for _, license := range disk.Licenses {
return imagetools.NormalizeImageInfo(license, "", "", "", "").OsDistro
}
}
}
return ""
}
func (instance *SInstance) GetBios() string {
return "BIOS"
}
func (instance *SInstance) GetMachine() string {
return "pc"
}
func (instance *SInstance) GetInstanceType() string {
instance.fetchMachineType()
return instance.machineType
}
func (instance *SInstance) AssignSecurityGroup(id string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) GetSecurityGroupIds() ([]string, error) {
secgroupIds := []string{}
isecgroups := []cloudprovider.ICloudSecurityGroup{}
for _, networkinterface := range instance.NetworkInterfaces {
globalnetwork, err := instance.host.zone.region.client.GetGlobalNetwork(networkinterface.Network)
if err != nil {
return nil, errors.Wrap(err, "GetGlobalNetwork")
}
vpc := &SVpc{globalnetwork: globalnetwork, region: instance.host.zone.region}
_isecgroups, err := vpc.GetISecurityGroups()
if err != nil {
return nil, errors.Wrap(err, "vpc.GetISecurityGroups")
}
isecgroups = append(isecgroups, _isecgroups...)
for _, isecgroup := range _isecgroups {
if len(instance.ServiceAccounts) > 0 && isecgroup.GetName() == instance.ServiceAccounts[0].Email {
secgroupIds = append(secgroupIds, isecgroup.GetGlobalId())
}
if isecgroup.GetName() == globalnetwork.GetName() {
secgroupIds = append(secgroupIds, isecgroup.GetGlobalId())
}
}
}
if len(instance.NetworkInterfaces) == 1 {
for _, secgroup := range isecgroups {
if utils.IsInStringArray(secgroup.GetName(), instance.Tags.Items) {
secgroupIds = append(secgroupIds, secgroup.GetGlobalId())
}
}
}
return secgroupIds, nil
}
func (instance *SInstance) SetSecurityGroups(ids []string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) GetHypervisor() string {
return api.HYPERVISOR_GOOGLE
}
func (instance *SInstance) StartVM(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) StopVM(ctx context.Context, isForce bool) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) DeleteVM(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) UpdateVM(ctx context.Context, name string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) UpdateUserData(userData string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) RebuildRoot(ctx context.Context, imageId string, passwd string, publicKey string, sysSizeGB int) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (instance *SInstance) DeployVM(ctx context.Context, name string, username string, password string, publicKey string, deleteKeypair bool, description string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (instance *SInstance) AttachDisk(ctx context.Context, diskId string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) DetachDisk(ctx context.Context, diskId string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) CreateDisk(ctx context.Context, sizeMb int, uuid string, driver string) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) Renew(bc billing.SBillingCycle) error {
return cloudprovider.ErrNotImplemented
}
func (instance *SInstance) GetError() error {
return nil
}
+58
View File
@@ -0,0 +1,58 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"yunion.io/x/log"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SNetworkInterface struct {
instance *SInstance
Network string
Subnetwork string
NetworkIP string
Name string
AccessConfigs []AccessConfig
Fingerprint string
Kind string
}
func (nic *SNetworkInterface) GetIP() string {
return nic.NetworkIP
}
func (nic *SNetworkInterface) GetMAC() string {
ip, _ := netutils.NewIPV4Addr(nic.NetworkIP)
return ip.ToMac("00:16:")
}
func (nic *SNetworkInterface) GetDriver() string {
return "virtio"
}
func (nic *SNetworkInterface) GetINetwork() cloudprovider.ICloudNetwork {
network, err := nic.instance.host.zone.region.GetNetwork(nic.Subnetwork)
if err != nil {
log.Errorf("failed to found network(%s) for nic error: %v", nic.Subnetwork, err)
return nil
}
wire := nic.instance.host.GetWire()
network.wire = wire
return network
}
@@ -0,0 +1,70 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
var LatitudeAndLongitude = map[string]cloudprovider.SGeographicInfo{
"asia-east1": {Latitude: 25.0443, Longitude: 121.509, City: api.CITY_TAI_WAN, CountryCode: api.COUNTRY_CODE_CN},
"asia-east2": {Latitude: 22.396427, Longitude: 114.109497, City: api.CITY_HONG_KONG, CountryCode: api.COUNTRY_CODE_CN},
"asia-northeast1": {Latitude: 35.709026, Longitude: 139.731995, City: api.CITY_TOKYO, CountryCode: api.COUNTRY_CODE_JP},
"asia-northeast2": {Latitude: 34.6937378, Longitude: 135.5021651, City: api.CITY_OSAKA, CountryCode: api.COUNTRY_CODE_JP},
"asia-south1": {Latitude: 19.075983, Longitude: 72.877655, City: api.CITY_MUMBAI, CountryCode: api.COUNTRY_CODE_IN},
"asia-southeast1": {Latitude: 1.352083, Longitude: 103.819839, City: api.CITY_SINGAPORE, CountryCode: api.COUNTRY_CODE_SG},
"australia-southeast1": {Latitude: -33.8688197, Longitude: 151.2092955, City: api.CITY_SYDNEY, CountryCode: api.COUNTRY_CODE_AU},
"europe-north1": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_FINLAND, CountryCode: api.COUNTRY_CODE_CN},
"europe-west1": {Latitude: 39.904202, Longitude: 116.407394, City: api.CITY_BELGIUM, CountryCode: api.COUNTRY_CODE_CN},
"europe-west2": {Latitude: 51.507351, Longitude: -0.127758, City: api.CITY_LONDON, CountryCode: api.COUNTRY_CODE_GB},
"europe-west3": {Latitude: 51.165691, Longitude: 10.451526, City: api.CITY_FRANKFURT, CountryCode: api.COUNTRY_CODE_DE},
"europe-west4": {Latitude: 52.2076831, Longitude: 4.1585786, City: api.CITY_HOLLAND, CountryCode: api.COUNTRY_CODE_NL},
"europe-west6": {Latitude: 47.3774497, Longitude: 8.5016958, City: api.CITY_ZURICH, CountryCode: api.COUNTRY_CODE_CH},
"northamerica-northeast1": {Latitude: 45.5580206, Longitude: -73.8003414, City: api.CITY_MONTREAL, CountryCode: api.COUNTRY_CODE_CA},
"southamerica-east1": {Latitude: -23.5505199, Longitude: -46.6333094, City: api.CITY_SAO_PAULO, CountryCode: api.COUNTRY_CODE_BR},
"us-central1": {Latitude: 41.9328655, Longitude: -94.5106809, City: api.CITY_IOWA, CountryCode: api.COUNTRY_CODE_US},
"us-east1": {Latitude: 33.6194409, Longitude: -82.0475635, City: api.CITY_SOUTH_CAROLINA, CountryCode: api.COUNTRY_CODE_US},
"us-east4": {Latitude: 37.4315734, Longitude: -78.6568942, City: api.CITY_N_VIRGINIA, CountryCode: api.COUNTRY_CODE_US},
"us-west1": {Latitude: 43.8041334, Longitude: -120.5542012, City: api.CITY_OREGON, CountryCode: api.COUNTRY_CODE_US},
"us-west2": {Latitude: 34.0522342, Longitude: -118.2436849, City: api.CITY_LOS_ANGELES, CountryCode: api.COUNTRY_CODE_US},
}
var RegionNames = map[string]string{
"asia-east1": "台湾",
"asia-east2": "香港",
"asia-northeast1": "东京",
"asia-northeast2": "大阪",
"asia-south1": "孟买",
"asia-southeast1": "新加坡",
"australia-southeast1": "悉尼",
"europe-north1": "芬兰",
"europe-west1": "比利时",
"europe-west2": "伦敦",
"europe-west3": "法兰克福",
"europe-west4": "荷兰",
"europe-west6": "苏黎世",
"northamerica-northeast1": "蒙特利尔",
"southamerica-east1": "圣保罗",
"us-central1": "艾奥瓦",
"us-east1": "南卡罗来纳州",
"us-east4": "北弗吉尼亚",
"us-west1": "俄勒冈州",
"us-west2": "洛杉矶",
}
+57
View File
@@ -0,0 +1,57 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SMachineType struct {
Id string
CreationTimestamp time.Time
Name string
Description string
GuestCpus int
MemoryMb int
ImageSpaceGb int
MaximumPersistentDisks int
MaximumPersistentDisksSizeGb int
Zone string
SelfLink string
IsSharedCpu bool
Kind string
}
func (region *SRegion) GetMachineTypes(zone string, maxResults int, pageToken string) ([]SMachineType, error) {
machines := []SMachineType{}
params := map[string]string{}
if len(zone) == 0 {
return nil, cloudprovider.ErrNotFound
}
resource := fmt.Sprintf("zones/%s/machineTypes", zone)
return machines, region.List(resource, params, maxResults, pageToken, &machines)
}
func (region *SRegion) GetMachineType(id string) (*SMachineType, error) {
machine := &SMachineType{}
err := region.client.get(id, machine)
if err != nil {
return nil, err
}
return machine, nil
}
+144
View File
@@ -0,0 +1,144 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/netutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type SNetwork struct {
wire *SWire
Id string
CreationTimestamp time.Time
Name string
Network string
IpCidrRange string
Region string
GatewayAddress string
SelfLink string
Status string
AvailableCpuPlatforms []string
PrivateIpGoogleAccess bool
Fingerprint string
Purpose string
Kind string
}
func (region *SRegion) GetNetworks(network string, maxResults int, pageToken string) ([]SNetwork, error) {
networks := []SNetwork{}
params := map[string]string{}
if len(network) > 0 {
params["filter"] = fmt.Sprintf(`network="%s"`, network)
}
resource := fmt.Sprintf("regions/%s/subnetworks", region.Name)
return networks, region.List(resource, params, maxResults, pageToken, &networks)
}
func (region *SRegion) GetNetwork(id string) (*SNetwork, error) {
network := &SNetwork{}
return network, region.Get(id, network)
}
func (network *SNetwork) GetId() string {
return network.SelfLink
}
func (network *SNetwork) GetName() string {
return network.Name
}
func (network *SNetwork) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (network *SNetwork) GetProjectId() string {
return network.wire.vpc.region.GetProjectId()
}
func (network *SNetwork) Refresh() error {
_network, err := network.wire.vpc.region.GetNetwork(network.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(network, _network)
}
func (network *SNetwork) IsEmulated() bool {
return false
}
func (network *SNetwork) GetStatus() string {
return api.NETWORK_INTERFACE_STATUS_AVAILABLE
}
func (network *SNetwork) GetGlobalId() string {
return getGlobalId(network.SelfLink)
}
func (network *SNetwork) Delete() error {
return cloudprovider.ErrNotImplemented
}
func (network *SNetwork) GetAllocTimeoutSeconds() int {
return 300
}
func (network *SNetwork) GetIWire() cloudprovider.ICloudWire {
return network.wire
}
func (network *SNetwork) GetIpStart() string {
pref, _ := netutils.NewIPV4Prefix(network.IpCidrRange)
startIp := pref.Address.NetAddr(pref.MaskLen) // 0
startIp = startIp.StepUp() // 1
return startIp.String()
}
func (network *SNetwork) GetIpEnd() string {
pref, _ := netutils.NewIPV4Prefix(network.IpCidrRange)
endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255
endIp = endIp.StepDown() // 254
return endIp.String()
}
func (network *SNetwork) GetIpMask() int8 {
pref, _ := netutils.NewIPV4Prefix(network.IpCidrRange)
return pref.MaskLen
}
func (network *SNetwork) GetGateway() string {
return network.GatewayAddress
}
func (network *SNetwork) GetServerType() string {
return api.NETWORK_TYPE_GUEST
}
func (network *SNetwork) GetIsPublic() bool {
return true
}
func (network *SNetwork) GetPublicScope() rbacutils.TRbacScope {
return rbacutils.ScopeDomain
}
+94
View File
@@ -0,0 +1,94 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
)
type SProject struct {
Name string
CreateTime time.Time
LifecycleState string
ProjectId string
ProjectNumber string
}
func (cli *SGoogleClient) GetProject(id string) (*SProject, error) {
project := &SProject{}
return project, cli.get(id, project)
}
func (cli *SGoogleClient) GetProjects() ([]SProject, error) {
baseUrl := "https://cloudresourcemanager.googleapis.com/v1/projects"
nextPageToken := ""
result := []SProject{}
for {
url := baseUrl
if len(nextPageToken) > 0 {
url = fmt.Sprintf("%s?pageToken=%s", baseUrl, nextPageToken)
}
data, err := jsonRequest(cli.client, "GET", url, nil, cli.Debug)
if err != nil {
return nil, errors.Wrap(err, "JSONRequest")
}
_result := []SProject{}
if data.Contains("projects") {
err = data.Unmarshal(&_result, "projects")
if err != nil {
return nil, errors.Wrap(err, "data.Unmarshal")
}
}
result = append(result, _result...)
nextPageToken, _ = data.GetString("nextPageToken")
if len(nextPageToken) == 0 || len(_result) == 0 {
break
}
}
return result, nil
}
func (p *SProject) GetName() string {
return p.Name
}
func (p *SProject) GetId() string {
return p.ProjectId
}
func (p *SProject) GetGlobalId() string {
return p.ProjectId
}
func (p *SProject) GetStatus() string {
return ""
}
func (p *SProject) Refresh() error {
return nil
}
func (p *SProject) IsEmulated() bool {
return false
}
func (p *SProject) GetMetadata() *jsonutils.JSONDict {
return nil
}
+1
View File
@@ -0,0 +1 @@
package provider // import "yunion.io/x/onecloud/pkg/multicloud/google/provider"
+191
View File
@@ -0,0 +1,191 @@
// Copyright 2019 Yunion
//
// 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.
package provider
import (
"context"
"fmt"
"strings"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/multicloud/google"
)
type SGoogleProviderFactory struct {
cloudprovider.SPublicCloudBaseProviderFactor
}
func (self *SGoogleProviderFactory) GetId() string {
return google.CLOUD_PROVIDER_GOOGLE
}
func (self *SGoogleProviderFactory) GetName() string {
return google.CLOUD_PROVIDER_GOOGLE_CN
}
func (self *SGoogleProviderFactory) ValidateChangeBandwidth(instanceId string, bandwidth int64) error {
return nil
}
func (self *SGoogleProviderFactory) IsSupportPrepaidResources() bool {
return true
}
func (self *SGoogleProviderFactory) NeedSyncSkuFromCloud() bool {
return false
}
func (self *SGoogleProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input *api.CloudaccountCreateInput) error {
for key, value := range map[string]string{
"client_email": input.ClientEmail,
"project_id": input.ProjectId,
"private_key_id": input.PrivateKeyId,
"private_key": input.PrivateKey,
} {
if len(value) == 0 {
return httperrors.NewMissingParameterError(key)
}
}
input.Account = fmt.Sprintf("%s/%s", input.ProjectId, input.ClientEmail)
input.Secret = fmt.Sprintf("%s/%s", input.PrivateKeyId, input.PrivateKey)
return nil
}
func (self *SGoogleProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, userCred mcclient.TokenCredential, input *api.CloudaccountCredentialInput, cloudaccount string) (*cloudprovider.SCloudaccount, error) {
projectID, clientEmail := "", ""
accountInfo := strings.Split(cloudaccount, "/")
if len(accountInfo) == 2 {
projectID, clientEmail = accountInfo[0], accountInfo[1]
}
for key, value := range map[string]string{
"private_key_id": input.PrivateKeyId,
"private_key": input.PrivateKey,
} {
if len(value) == 0 {
return nil, httperrors.NewMissingParameterError(key)
}
}
if len(input.ClientEmail) == 0 {
input.ClientEmail = clientEmail
}
if len(input.ProjectId) == 0 {
input.ProjectId = projectID
}
account := &cloudprovider.SCloudaccount{
Account: fmt.Sprintf("%s/%s", input.ProjectId, input.ClientEmail),
Secret: fmt.Sprintf("%s/%s", input.PrivateKeyId, input.PrivateKey),
}
return account, nil
}
func (self *SGoogleProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
privateKeyID, privateKey := "", ""
privateKeyInfo := strings.Split(secret, "/")
if len(privateKeyInfo) < 2 {
return nil, fmt.Errorf("Missing privateKeyID or privateKey for google cloud")
}
privateKeyID = privateKeyInfo[0]
privateKey = strings.Join(privateKeyInfo[1:], "/")
projectID, clientEmail := "", ""
accountInfo := strings.Split(account, "/")
if len(accountInfo) < 2 {
return nil, fmt.Errorf("Invalid projectID or client email for google cloud %s", account)
}
projectID, clientEmail = accountInfo[0], accountInfo[1]
client, err := google.NewGoogleClient(providerId, providerName, projectID, clientEmail, privateKeyID, privateKey, false)
if err != nil {
return nil, err
}
return &SGoogleProvider{
SBaseProvider: cloudprovider.NewBaseProvider(self),
client: client,
}, nil
}
func (self *SGoogleProviderFactory) GetClientRC(url, account, secret string) (map[string]string, error) {
return map[string]string{
"ALIYUN_ACCESS_KEY": account,
"ALIYUN_SECRET": secret,
"ALIYUN_REGION": google.GOOGLE_DEFAULT_REGION,
}, nil
}
func init() {
factory := SGoogleProviderFactory{}
cloudprovider.RegisterFactory(&factory)
}
type SGoogleProvider struct {
cloudprovider.SBaseProvider
client *google.SGoogleClient
}
func (self *SGoogleProvider) GetSysInfo() (jsonutils.JSONObject, error) {
regions := self.client.GetIRegions()
info := jsonutils.NewDict()
info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
info.Add(jsonutils.NewString(google.GOOGLE_API_VERSION), "api_version")
return info, nil
}
func (self *SGoogleProvider) GetVersion() string {
return google.GOOGLE_API_VERSION
}
func (self *SGoogleProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return self.client.GetSubAccounts()
}
func (self *SGoogleProvider) GetAccountId() string {
return self.client.GetAccountId()
}
func (self *SGoogleProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (self *SGoogleProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return self.client.GetIGlobalnetworks()
}
func (self *SGoogleProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return self.client.GetIGlobalnetworkById(id)
}
func (self *SGoogleProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(extId)
}
func (self *SGoogleProvider) GetBalance() (float64, string, error) {
return 0.0, api.CLOUD_PROVIDER_HEALTH_NORMAL, cloudprovider.ErrNotSupported
}
func (self *SGoogleProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) {
return self.client.GetIProjects()
}
func (self *SGoogleProvider) GetStorageClasses(regionId string) []string {
return []string{
"Standard", "IA", "Archive",
}
}
+300
View File
@@ -0,0 +1,300 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SRegion struct {
cloudprovider.SFakeOnPremiseRegion
multicloud.SRegion
multicloud.SNoObjectStorageRegion
client *SGoogleClient
Description string
ID string
Kind string
Name string
Status string
SelfLink string
CreationTimestamp time.Time
}
func (region *SRegion) GetClient() *SGoogleClient {
return region.client
}
func (region *SRegion) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (region *SRegion) GetName() string {
if name, ok := RegionNames[region.Name]; ok {
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE_CN, name)
}
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE_CN, region.Name)
}
func (region *SRegion) GetId() string {
return region.Name
}
func (region *SRegion) GetGlobalId() string {
return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_GOOGLE, region.Name)
}
func (region *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
if geoInfo, ok := LatitudeAndLongitude[region.Name]; ok {
return geoInfo
}
return cloudprovider.SGeographicInfo{}
}
func (region *SRegion) GetProvider() string {
return CLOUD_PROVIDER_GOOGLE
}
func (region *SRegion) GetStatus() string {
if region.Status == "UP" {
return api.CLOUD_REGION_STATUS_INSERVER
}
return api.CLOUD_REGION_STATUS_OUTOFSERVICE
}
func (region *SRegion) IsEmulated() bool {
return false
}
func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
zones, err := region.GetZones(region.Name, 0, "")
if err != nil {
return nil, err
}
izones := []cloudprovider.ICloudZone{}
for i := 0; i < len(zones); i++ {
zones[i].region = region
izones = append(izones, &zones[i])
}
return izones, nil
}
func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
zones, err := region.GetIZones()
if err != nil {
return nil, err
}
for i := range zones {
if zones[i].GetGlobalId() == id {
return zones[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (region *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
globalnetworks, err := region.client.fetchGlobalNetwork()
if err != nil {
return nil, errors.Wrap(err, "fetchGlobalNetwork")
}
substr := fmt.Sprintf("regions/%s/subnetworks", region.Name)
ivpcs := []cloudprovider.ICloudVpc{}
for i := range globalnetworks {
for _, subnet := range globalnetworks[i].Subnetworks {
if strings.Index(subnet, substr) >= 0 {
vpc := SVpc{region: region, globalnetwork: &globalnetworks[i]}
ivpcs = append(ivpcs, &vpc)
}
}
}
return ivpcs, nil
}
func (region *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
ivpcs, err := region.GetIVpcs()
if err != nil {
return nil, err
}
for i := range ivpcs {
if ivpcs[i].GetGlobalId() == id {
return ivpcs[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (region *SRegion) GetUrlPrefixWithProjectId() string {
return getUrlPrefix() + region.GetProjectId()
}
func (region *SRegion) GetProjectId() string {
return region.client.projectId
}
func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
eips, err := region.GetEips("", 0, "")
if err != nil {
return nil, err
}
ieips := []cloudprovider.ICloudEIP{}
for i := range eips {
eips[i].region = region
ieips = append(ieips, &eips[i])
}
return ieips, nil
}
func (region *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
ivm, err := region.GetInstance(id)
if err != nil {
return nil, err
}
return ivm, nil
}
func (region *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
disk, err := region.GetDisk(id)
if err != nil {
return nil, err
}
return disk, nil
}
func (region *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
eip, err := region.GetEip(id)
if err != nil {
return nil, err
}
return eip, nil
}
func (region *SRegion) fetchSnapshots() error {
if len(region.client.snapshots) > 0 {
return nil
}
region.client.snapshots = map[string][]SSnapshot{}
snapshots, err := region.GetSnapshots("", 0, "")
if err != nil {
return err
}
regionNames := []string{}
for _, region := range region.client.iregions {
regionNames = append(regionNames, region.GetId())
}
for _, snapshot := range snapshots {
for _, location := range snapshot.StorageLocations {
_regionName := ""
if utils.IsInStringArray(location, regionNames) {
_regionName = location
} else {
for _, regionName := range regionNames {
if strings.HasPrefix(regionName, location) {
_regionName = regionName
break
}
}
}
if len(_regionName) > 0 {
if _, ok := region.client.snapshots[_regionName]; !ok {
region.client.snapshots[_regionName] = []SSnapshot{}
}
region.client.snapshots[_regionName] = append(region.client.snapshots[_regionName], snapshot)
break
}
}
}
return nil
}
func (region *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
region.fetchSnapshots()
isnapshots := []cloudprovider.ICloudSnapshot{}
if snapshots, ok := region.client.snapshots[region.Name]; ok {
for i := range snapshots {
snapshots[i].region = region
isnapshots = append(isnapshots, &snapshots[i])
}
}
return isnapshots, nil
}
func (region *SRegion) GetISnapshotById(id string) (cloudprovider.ICloudSnapshot, error) {
snapshot, err := region.GetSnapshot(id)
if err != nil {
return nil, err
}
return snapshot, nil
}
func (region *SRegion) ListAll(resource string, params map[string]string, retval interface{}) error {
return region.client.listAll(resource, params, retval)
}
func (region *SRegion) List(resource string, params map[string]string, maxResults int, pageToken string, retval interface{}) error {
return region.client.list(resource, params, maxResults, pageToken, retval)
}
func (region *SRegion) Get(id string, retval interface{}) error {
return region.client.get(id, retval)
}
func (region *SRegion) fetchResourcePolicies() ([]SResourcePolicy, error) {
if len(region.client.resourcepolices) > 0 {
return region.client.resourcepolices, nil
}
policies, err := region.GetResourcePolicies(0, "")
if err != nil {
return nil, err
}
region.client.resourcepolices = policies
return policies, nil
}
func (region *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
policies, err := region.fetchResourcePolicies()
if err != nil {
return nil, err
}
ipolicies := []cloudprovider.ICloudSnapshotPolicy{}
for i := range policies {
policies[i].region = region
if strings.Contains(region.Name, policies[i].SnapshotSchedulePolicy.SnapshotProperties.StorageLocations[0]) {
ipolicies = append(ipolicies, &policies[i])
}
}
return ipolicies, nil
}
func (region *SRegion) GetISnapshotPolicyById(id string) (cloudprovider.ICloudSnapshotPolicy, error) {
policy, err := region.GetResourcePolicy(id)
if err != nil {
return nil, err
}
if !strings.Contains(region.Name, policy.SnapshotSchedulePolicy.SnapshotProperties.StorageLocations[0]) {
return nil, cloudprovider.ErrNotFound
}
return policy, nil
}
+53
View File
@@ -0,0 +1,53 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
)
type SRegionDisk struct {
storage *SStorage
Id string
CreationTimestamp time.Time
Name string
SizeGB int
Zone string
Status string
SelfLink string
Type string
LastAttachTimestamp time.Time
LastDetachTimestamp time.Time
LabelFingerprint string
PhysicalBlockSizeBytes string
Kind string
}
func (region *SRegion) GetRegionDisks(storageType string, maxResults int, pageToken string) ([]SRegionDisk, error) {
disks := []SRegionDisk{}
params := map[string]string{}
if len(storageType) > 0 {
params["filter"] = fmt.Sprintf(`type="%s/regions/%s/diskTypes/%s"`, region.GetUrlPrefixWithProjectId(), region.Name, storageType)
}
resource := fmt.Sprintf("regions/%s/disks", region.Name)
return disks, region.List(resource, params, maxResults, pageToken, &disks)
}
func (region *SRegion) GetRegionDisk(id string) (*SRegionDisk, error) {
disk := &SRegionDisk{}
return disk, region.Get(id, disk)
}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
)
type SRegionStorage struct {
region *SRegion
CreationTimestamp time.Time
Name string
Description string
ValidDiskSize string
Zone string
SelfLink string
DefaultDiskSizeGb string
Kind string
}
func (region *SRegion) GetRegionStorages(maxResults int, pageToken string) ([]SRegionStorage, error) {
storages := []SRegionStorage{}
resource := fmt.Sprintf("regions/%s/diskTypes", region.Name)
params := map[string]string{}
return storages, region.List(resource, params, maxResults, pageToken, &storages)
}
func (region *SRegion) GetRegionStorage(id string) (*SRegionStorage, error) {
storage := &SRegionStorage{region: region}
return storage, region.Get(id, storage)
}
+177
View File
@@ -0,0 +1,177 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"strconv"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
)
type SDailySchedule struct {
DaysInCycle int
StartTime string
Duration string
}
type SDayOfWeek struct {
Day string
StartTime string
Duration string
}
type SHourlySchedule struct {
HoursInCycle int
StartTime string
Duration string
}
type SWeeklySchedule struct {
DayOfWeeks []SDayOfWeek
}
type SSchedule struct {
WeeklySchedule SWeeklySchedule
DailySchedule SDailySchedule
HourlySchedule SHourlySchedule
}
type SRetentionPolicy struct {
MaxRetentionDays int
OnSourceDiskDelete string
}
type SSnapshotProperties struct {
StorageLocations []string
GuestFlush bool
}
type SSnapshotSchedulePolicy struct {
Schedule SSchedule
RetentionPolicy SRetentionPolicy
SnapshotProperties SSnapshotProperties
}
type SResourcePolicy struct {
region *SRegion
Id string
CreationTimestamp time.Time
SelfLink string
Region string
Name string
Status string
Kind string
SnapshotSchedulePolicy SSnapshotSchedulePolicy `json:"snapshotSchedulePolicy"`
}
func (region *SRegion) GetResourcePolicies(maxResults int, pageToken string) ([]SResourcePolicy, error) {
policies := []SResourcePolicy{}
resource := fmt.Sprintf("regions/%s/resourcePolicies", region.Name)
params := map[string]string{}
return policies, region.List(resource, params, maxResults, pageToken, &policies)
}
func (region *SRegion) GetResourcePolicy(id string) (*SResourcePolicy, error) {
policy := &SResourcePolicy{region: region}
return policy, region.Get(id, policy)
}
func (policy *SResourcePolicy) GetId() string {
return getGlobalId(policy.SelfLink)
}
func (policy *SResourcePolicy) GetGlobalId() string {
return policy.GetId()
}
func (policy *SResourcePolicy) GetName() string {
return policy.Name
}
func (policy *SResourcePolicy) GetStatus() string {
switch policy.Status {
case "READY":
return api.SNAPSHOT_POLICY_READY
default:
log.Errorf("unknown policy status %s", policy.Status)
return api.SNAPSHOT_POLICY_UNKNOWN
}
}
func (policy *SResourcePolicy) Refresh() error {
_policy, err := policy.region.GetResourcePolicy(policy.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(policy, _policy)
}
func (policy *SResourcePolicy) IsEmulated() bool {
return false
}
func (policy *SResourcePolicy) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (policy *SResourcePolicy) GetProjectId() string {
return policy.region.GetProjectId()
}
func (policy *SResourcePolicy) GetRetentionDays() int {
return policy.SnapshotSchedulePolicy.RetentionPolicy.MaxRetentionDays
}
func (policy *SResourcePolicy) GetRepeatWeekdays() ([]int, error) {
result := []int{1, 2, 3, 4, 5, 6, 7}
if len(policy.SnapshotSchedulePolicy.Schedule.WeeklySchedule.DayOfWeeks) > 0 {
return nil, fmt.Errorf("current not support dayOfWeeks")
}
if policy.SnapshotSchedulePolicy.Schedule.HourlySchedule.HoursInCycle != 0 {
return nil, fmt.Errorf("current not support hourlySchedule")
}
return result, nil
}
func (policy *SResourcePolicy) GetTimePoints() ([]int, error) {
result := []int{}
if len(policy.SnapshotSchedulePolicy.Schedule.DailySchedule.StartTime) == 0 {
return nil, fmt.Errorf("current only support dailySchedule")
}
if startInfo := strings.Split(policy.SnapshotSchedulePolicy.Schedule.DailySchedule.StartTime, ":"); len(startInfo) >= 2 {
point, err := strconv.Atoi(startInfo[0])
if err != nil {
return nil, errors.Wrapf(err, "convert %s", policy.SnapshotSchedulePolicy.Schedule.DailySchedule.StartTime)
}
result = append(result, point)
if startInfo[1] != "00" {
result = append(result, point+1)
}
}
return result, nil
}
func (policy *SResourcePolicy) IsActivated() bool {
return true
}
+302
View File
@@ -0,0 +1,302 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"net"
"sort"
"strconv"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SFirewallAction struct {
IPProtocol string
Ports []string
}
type SFirewall struct {
Id string
CreationTimestamp time.Time
Name string
Description string
Network string
Priority int
SourceRanges []string
TargetServiceAccounts []string
TargetTags []string
Allowed []SFirewallAction
Denied []SFirewallAction
Direction string
Disabled bool
SelfLink string
Kind string
}
type FirewallSet []SFirewall
func (f FirewallSet) Len() int {
return len(f)
}
func (f FirewallSet) Swap(i, j int) {
f[i], f[j] = f[j], f[i]
}
func (f FirewallSet) Less(i, j int) bool {
if f[i].Priority != f[j].Priority {
return f[i].Priority < f[j].Priority
}
return len(f[i].Allowed) < len(f[j].Allowed)
}
type SSecurityGroup struct {
vpc *SVpc
ServiceAccount string
Tag string
}
func (region *SRegion) GetFirewalls(network string, maxResults int, pageToken string) ([]SFirewall, error) {
firewalls := []SFirewall{}
params := map[string]string{"filter": "disabled = false"}
resource := "global/firewalls"
return firewalls, region.List(resource, params, maxResults, pageToken, &firewalls)
}
func (region *SRegion) GetFirewall(id string) (*SFirewall, error) {
firewall := &SFirewall{}
return firewall, region.Get(id, firewall)
}
func (firewall *SFirewall) _toRules(action secrules.TSecurityRuleAction) ([]secrules.SecurityRule, error) {
rules := []secrules.SecurityRule{}
list := firewall.Allowed
if action == secrules.SecurityRuleDeny {
list = firewall.Denied
}
for _, allow := range list {
rule := secrules.SecurityRule{
Action: action,
Direction: secrules.DIR_IN,
Description: firewall.Description,
Priority: firewall.Priority,
}
if firewall.Direction == "EGRESS" {
rule.Direction = secrules.DIR_OUT
}
switch allow.IPProtocol {
case "tcp", "udp", "icmp":
rule.Protocol = allow.IPProtocol
case "all":
rule.Protocol = secrules.PROTO_ANY
default:
return nil, fmt.Errorf("unsupport protocol %s", allow.IPProtocol)
}
for _, sourceRange := range firewall.SourceRanges {
if regutils.MatchCIDR(sourceRange) {
_, rule.IPNet, _ = net.ParseCIDR(sourceRange)
} else {
rule.IPNet = &net.IPNet{
IP: net.ParseIP(sourceRange),
Mask: net.CIDRMask(32, 32),
}
}
ports := []int{}
for _, port := range allow.Ports {
if strings.Index(port, "-") > 0 {
err := rule.ParsePorts(port)
if err != nil {
return nil, errors.Wrapf(err, "Parse port %s", port)
}
rules = append(rules, rule)
} else {
_port, err := strconv.Atoi(port)
if err != nil {
return nil, errors.Wrapf(err, "Atio port %s", port)
}
ports = append(ports, _port)
}
}
if len(ports) > 0 {
rule.Ports = ports
rule.PortStart = -1
rule.PortEnd = -1
rules = append(rules, rule)
}
}
}
return rules, nil
}
func (firewall *SFirewall) toRules() ([]secrules.SecurityRule, error) {
rules := []secrules.SecurityRule{}
_rules, err := firewall._toRules(secrules.SecurityRuleAllow)
if err != nil {
return nil, err
}
rules = append(rules, _rules...)
_rules, err = firewall._toRules(secrules.SecurityRuleDeny)
if err != nil {
return nil, err
}
rules = append(rules, _rules...)
return rules, nil
}
func (secgroup *SSecurityGroup) GetId() string {
return secgroup.vpc.globalnetwork.GetGlobalId()
}
func (secgroup *SSecurityGroup) GetGlobalId() string {
if len(secgroup.Tag) > 0 {
return fmt.Sprintf("%s/%s", secgroup.GetId(), secgroup.Tag)
}
if len(secgroup.ServiceAccount) > 0 {
return fmt.Sprintf("%s/%s", secgroup.GetId(), secgroup.ServiceAccount)
}
return secgroup.GetId()
}
func (secgroup *SSecurityGroup) GetDescription() string {
return ""
}
func (secgroup *SSecurityGroup) GetName() string {
if len(secgroup.Tag) > 0 {
return secgroup.Tag
}
if len(secgroup.ServiceAccount) > 0 {
return secgroup.ServiceAccount
}
return secgroup.vpc.globalnetwork.GetName()
}
func (secgroup *SSecurityGroup) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (secgroup *SSecurityGroup) GetStatus() string {
return ""
}
func (secgroup *SSecurityGroup) IsEmulated() bool {
return false
}
func (secgroup *SSecurityGroup) Refresh() error {
return nil
}
func (secgroup *SSecurityGroup) Delete() error {
return nil
}
func (secgroup *SSecurityGroup) GetProjectId() string {
return ""
}
func (secgroup *SSecurityGroup) GetVpcId() string {
return secgroup.vpc.GetGlobalId()
}
func (self *SSecurityGroup) GetRules() ([]secrules.SecurityRule, error) {
_firewalls, err := self.vpc.region.GetFirewalls(self.vpc.globalnetwork.SelfLink, 0, "")
if err != nil {
return nil, err
}
firewalls := []SFirewall{}
for _, firewall := range _firewalls {
if len(self.Tag) > 0 && utils.IsInStringArray(self.Tag, firewall.TargetTags) {
firewalls = append(firewalls, firewall)
} else if len(self.ServiceAccount) > 0 && utils.IsInStringArray(self.ServiceAccount, firewall.TargetServiceAccounts) {
firewalls = append(firewalls, firewall)
} else {
if len(self.Tag) == 0 && len(self.ServiceAccount) == 0 && len(firewall.TargetServiceAccounts) == 0 && len(firewall.TargetTags) == 0 {
firewalls = append(firewalls, firewall)
}
}
}
sort.Sort(FirewallSet(firewalls))
rules := []secrules.SecurityRule{}
priority := 100
for _, firewall := range firewalls {
firewall.Priority = priority
if priority > 2 {
priority--
}
_rules, err := firewall.toRules()
if err != nil {
return nil, err
}
rules = append(rules, _rules...)
}
return rules, nil
}
func (secgroup *SSecurityGroup) SyncRules(rules []secrules.SecurityRule) error {
return cloudprovider.ErrNotImplemented
}
func (region *SRegion) GetISecurityGroupById(id string) (cloudprovider.ICloudSecurityGroup, error) {
vpcs, err := region.GetIVpcs()
if err != nil {
return nil, errors.Wrap(err, "GetIVpcs")
}
for _, vpc := range vpcs {
secgroups, err := vpc.GetISecurityGroups()
if err != nil {
return nil, errors.Wrap(err, "GetISecurityGroups")
}
for _, secgroup := range secgroups {
if secgroup.GetGlobalId() == id {
return secgroup, nil
}
}
}
return nil, cloudprovider.ErrNotFound
}
func (region *SRegion) GetISecurityGroupByName(vpcId string, name string) (cloudprovider.ICloudSecurityGroup, error) {
ivpc, err := region.GetIVpcById(vpcId)
if err != nil {
return nil, err
}
secgroups, err := ivpc.GetISecurityGroups()
if err != nil {
return nil, errors.Wrap(err, "ivpc.GetISecurityGroups")
}
for _, secgroup := range secgroups {
if secgroup.GetName() == name {
return secgroup, nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return region.GetISecurityGroupByName(conf.VpcId, "")
}
+76
View File
@@ -0,0 +1,76 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type DiskListOptions struct {
ZONE string
StorageType string
MaxResults int
PageToken string
}
shellutils.R(&DiskListOptions{}, "disk-list", "List disks", func(cli *google.SRegion, args *DiskListOptions) error {
disks, err := cli.GetDisks(args.ZONE, args.StorageType, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(disks, 0, 0, 0, nil)
return nil
})
type DiskShowOptions struct {
ID string
}
shellutils.R(&DiskShowOptions{}, "disk-show", "Show disk", func(cli *google.SRegion, args *DiskShowOptions) error {
disk, err := cli.GetDisk(args.ID)
if err != nil {
return err
}
printObject(disk)
return nil
})
type RegionDiskListOptions struct {
StorageType string
MaxResults int
PageToken string
}
shellutils.R(&RegionDiskListOptions{}, "region-disk-list", "List region disks", func(cli *google.SRegion, args *RegionDiskListOptions) error {
disks, err := cli.GetRegionDisks(args.StorageType, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(disks, 0, 0, 0, nil)
return nil
})
type RegionDiskShowOptions struct {
ID string
}
shellutils.R(&RegionDiskShowOptions{}, "region-disk-show", "Show region disk", func(cli *google.SRegion, args *RegionDiskShowOptions) error {
disk, err := cli.GetRegionDisk(args.ID)
if err != nil {
return err
}
printObject(disk)
return nil
})
}
+1
View File
@@ -0,0 +1 @@
package shell // import "yunion.io/x/onecloud/pkg/multicloud/google/shell"
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type EipListOptions struct {
Address string
MaxResults int
PageToken string
}
shellutils.R(&EipListOptions{}, "eip-list", "List eips", func(cli *google.SRegion, args *EipListOptions) error {
eips, err := cli.GetEips(args.Address, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(eips, 0, 0, 0, nil)
return nil
})
type EipShowOptions struct {
ID string
}
shellutils.R(&EipShowOptions{}, "eip-show", "Show eip", func(cli *google.SRegion, args *EipShowOptions) error {
eip, err := cli.GetEip(args.ID)
if err != nil {
return err
}
printObject(eip)
return nil
})
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type FirewallListOptions struct {
Network string
MaxResults int
PageToken string
}
shellutils.R(&FirewallListOptions{}, "firewall-list", "List firewalls", func(cli *google.SRegion, args *FirewallListOptions) error {
firewalls, err := cli.GetFirewalls(args.Network, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(firewalls, 0, 0, 0, nil)
return nil
})
type FirewallShowOptions struct {
ID string
}
shellutils.R(&FirewallShowOptions{}, "firewall-show", "Show firewall", func(cli *google.SRegion, args *FirewallShowOptions) error {
firewall, err := cli.GetFirewall(args.ID)
if err != nil {
return err
}
printObject(firewall)
return nil
})
}
@@ -0,0 +1,48 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type GlobalNetworkListOptions struct {
MaxResults int
PageToken string
}
shellutils.R(&GlobalNetworkListOptions{}, "global-network-list", "List globalnetworks", func(cli *google.SRegion, args *GlobalNetworkListOptions) error {
globalnetworks, err := cli.GetClient().GetGlobalNetworks(args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(globalnetworks, 0, 0, 0, nil)
return nil
})
type GlobalNetworkShowOptions struct {
ID string
}
shellutils.R(&GlobalNetworkShowOptions{}, "global-network-show", "Show globalnetwork", func(cli *google.SRegion, args *GlobalNetworkShowOptions) error {
globalnetwork, err := cli.GetClient().GetGlobalNetwork(args.ID)
if err != nil {
return err
}
printObject(globalnetwork)
return nil
})
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type ImageListOptions struct {
Project string
MaxResults int
PageToken string
}
shellutils.R(&ImageListOptions{}, "image-list", "List images", func(cli *google.SRegion, args *ImageListOptions) error {
images, err := cli.GetImages(args.Project, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(images, 0, 0, 0, nil)
return nil
})
type ImageShowOptions struct {
ID string
}
shellutils.R(&ImageShowOptions{}, "image-show", "Show image", func(cli *google.SRegion, args *ImageShowOptions) error {
image, err := cli.GetImage(args.ID)
if err != nil {
return err
}
printObject(image)
return nil
})
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type InstanceListOptions struct {
ZONE string
MaxResults int
PageToken string
}
shellutils.R(&InstanceListOptions{}, "instance-list", "List instances", func(cli *google.SRegion, args *InstanceListOptions) error {
instances, err := cli.GetInstances(args.ZONE, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(instances, 0, 0, 0, nil)
return nil
})
type InstanceShowOptions struct {
ID string
}
shellutils.R(&InstanceShowOptions{}, "instance-show", "Show instance", func(cli *google.SRegion, args *InstanceShowOptions) error {
instance, err := cli.GetInstance(args.ID)
if err != nil {
return err
}
printObject(instance)
return nil
})
}
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type MachineTypeListOptions struct {
ZONE string
MaxResults int
PageToken string
}
shellutils.R(&MachineTypeListOptions{}, "machine-type-list", "List machinetypes", func(cli *google.SRegion, args *MachineTypeListOptions) error {
machinetypes, err := cli.GetMachineTypes(args.ZONE, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(machinetypes, 0, 0, 0, nil)
return nil
})
type MachineTypeShowOptions struct {
ID string
}
shellutils.R(&MachineTypeShowOptions{}, "machine-type-show", "Show machinetype", func(cli *google.SRegion, args *MachineTypeShowOptions) error {
machinetype, err := cli.GetMachineType(args.ID)
if err != nil {
return err
}
printObject(machinetype)
return nil
})
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type NetworkListOptions struct {
Network string
MaxResults int
PageToken string
}
shellutils.R(&NetworkListOptions{}, "network-list", "List networks", func(cli *google.SRegion, args *NetworkListOptions) error {
networks, err := cli.GetNetworks(args.Network, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(networks, 0, 0, 0, nil)
return nil
})
type NetworkShowOptions struct {
ID string
}
shellutils.R(&NetworkShowOptions{}, "network-show", "Show network", func(cli *google.SRegion, args *NetworkShowOptions) error {
network, err := cli.GetNetwork(args.ID)
if err != nil {
return err
}
printObject(network)
return nil
})
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import "yunion.io/x/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)
}
+35
View File
@@ -0,0 +1,35 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type ProjectListOptions struct {
MaxResults int
PageToken string
}
shellutils.R(&ProjectListOptions{}, "project-list", "List projects", func(cli *google.SRegion, args *ProjectListOptions) error {
projects, err := cli.GetClient().GetProjects()
if err != nil {
return err
}
printList(projects, 0, 0, 0, nil)
return nil
})
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type RegionListOptions struct {
}
shellutils.R(&RegionListOptions{}, "region-list", "List regions", func(cli *google.SRegion, args *RegionListOptions) error {
regions := cli.GetClient().GetRegions()
printList(regions, 0, 0, 0, nil)
return nil
})
}
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type ResourcePolicyListOptions struct {
Disk string
MaxResults int
PageToken string
}
shellutils.R(&ResourcePolicyListOptions{}, "resource-policy-list", "List resourcepolicys", func(cli *google.SRegion, args *ResourcePolicyListOptions) error {
resourcepolicys, err := cli.GetResourcePolicies(args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(resourcepolicys, 0, 0, 0, nil)
return nil
})
type ResourcePolicyShowOptions struct {
ID string
}
shellutils.R(&ResourcePolicyShowOptions{}, "resource-policy-show", "Show resourcepolicy", func(cli *google.SRegion, args *ResourcePolicyShowOptions) error {
resourcepolicy, err := cli.GetResourcePolicy(args.ID)
if err != nil {
return err
}
printObject(resourcepolicy)
return nil
})
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type SnapshotListOptions struct {
Disk string
MaxResults int
PageToken string
}
shellutils.R(&SnapshotListOptions{}, "snapshot-list", "List snapshots", func(cli *google.SRegion, args *SnapshotListOptions) error {
snapshots, err := cli.GetSnapshots(args.Disk, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(snapshots, 0, 0, 0, nil)
return nil
})
type SnapshotShowOptions struct {
ID string
}
shellutils.R(&SnapshotShowOptions{}, "snapshot-show", "Show snapshot", func(cli *google.SRegion, args *SnapshotShowOptions) error {
snapshot, err := cli.GetSnapshot(args.ID)
if err != nil {
return err
}
printObject(snapshot)
return nil
})
}
+74
View File
@@ -0,0 +1,74 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type StorageListOptions struct {
ZONE string
MaxResults int
PageToken string
}
shellutils.R(&StorageListOptions{}, "storage-list", "List storages", func(cli *google.SRegion, args *StorageListOptions) error {
storages, err := cli.GetStorages(args.ZONE, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(storages, 0, 0, 0, nil)
return nil
})
type StorageShowOptions struct {
ID string
}
shellutils.R(&StorageShowOptions{}, "storage-show", "Show storage", func(cli *google.SRegion, args *StorageShowOptions) error {
storage, err := cli.GetStorage(args.ID)
if err != nil {
return err
}
printObject(storage)
return nil
})
type RegionStorageListOptions struct {
MaxResults int
PageToken string
}
shellutils.R(&RegionStorageListOptions{}, "region-storage-list", "List region storages", func(cli *google.SRegion, args *RegionStorageListOptions) error {
storages, err := cli.GetRegionStorages(args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(storages, 0, 0, 0, nil)
return nil
})
type RegionStorageShowOptions struct {
ID string
}
shellutils.R(&RegionStorageShowOptions{}, "region-storage-show", "Show region storage", func(cli *google.SRegion, args *RegionStorageShowOptions) error {
storage, err := cli.GetRegionStorage(args.ID)
if err != nil {
return err
}
printObject(storage)
return nil
})
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// 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.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/google"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type ZoneListOptions struct {
RegionId string
MaxResults int
PageToken string
}
shellutils.R(&ZoneListOptions{}, "zone-list", "List zones", func(cli *google.SRegion, args *ZoneListOptions) error {
zones, err := cli.GetZones(args.RegionId, args.MaxResults, args.PageToken)
if err != nil {
return err
}
printList(zones, 0, 0, 0, nil)
return nil
})
type ZoneShowOptions struct {
ID string
}
shellutils.R(&ZoneShowOptions{}, "zone-show", "Show zones", func(cli *google.SRegion, args *ZoneShowOptions) error {
zone, err := cli.GetZone(args.ID)
if err != nil {
return err
}
printObject(zone)
return nil
})
}
+127
View File
@@ -0,0 +1,127 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SSnapshot struct {
region *SRegion
Id string
CreationTimestamp time.Time
Name string
Status string
SourceDisk string
SourceDiskId string
DiskSizeGb int32
StorageBytes int
StorageBytesStatus string
Licenses []string
SelfLink string
LabelFingerprint string
LicenseCodes []string
StorageLocations []string
Kind string
}
func (region *SRegion) GetSnapshots(disk string, maxResults int, pageToken string) ([]SSnapshot, error) {
snapshots := []SSnapshot{}
params := map[string]string{}
if len(disk) > 0 {
params["filter"] = fmt.Sprintf(`sourceDisk="%s"`, disk)
}
resource := "global/snapshots"
return snapshots, region.List(resource, params, maxResults, pageToken, &snapshots)
}
func (region *SRegion) GetSnapshot(id string) (*SSnapshot, error) {
snapshot := &SSnapshot{region: region}
return snapshot, region.Get(id, snapshot)
}
func (snapshot *SSnapshot) GetId() string {
return snapshot.SelfLink
}
func (snapshot *SSnapshot) GetGlobalId() string {
return getGlobalId(snapshot.SelfLink)
}
func (snapshot *SSnapshot) GetName() string {
return snapshot.Name
}
//CREATING, DELETING, FAILED, READY, or UPLOADING
func (snapshot *SSnapshot) GetStatus() string {
switch snapshot.Status {
case "CREATING":
return api.SNAPSHOT_CREATING
case "DELETING":
return api.SNAPSHOT_DELETING
case "FAILED":
return api.SNAPSHOT_UNKNOWN
case "READY", "UPLOADING":
return api.SNAPSHOT_READY
default:
return api.SNAPSHOT_UNKNOWN
}
}
func (snapshot *SSnapshot) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (snapshot *SSnapshot) IsEmulated() bool {
return false
}
func (snapshot *SSnapshot) Refresh() error {
_snapshot, err := snapshot.region.GetSnapshot(snapshot.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(snapshot, _snapshot)
}
func (snapshot *SSnapshot) GetSizeMb() int32 {
return snapshot.DiskSizeGb * 1024
}
func (snapshot *SSnapshot) GetDiskId() string {
return snapshot.SourceDisk
}
func (snapshot *SSnapshot) GetDiskType() string {
if len(snapshot.Licenses) > 0 {
return api.DISK_TYPE_SYS
}
return api.DISK_TYPE_DATA
}
func (snapshot *SSnapshot) Delete() error {
return cloudprovider.ErrNotImplemented
}
func (snapshot *SSnapshot) GetProjectId() string {
return snapshot.region.GetProjectId()
}
+145
View File
@@ -0,0 +1,145 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"time"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SStorage struct {
zone *SZone
CreationTimestamp time.Time
Name string
Description string
ValidDiskSize string
Zone string
SelfLink string
DefaultDiskSizeGb string
Kind string
}
func (region *SRegion) GetStorages(zone string, maxResults int, pageToken string) ([]SStorage, error) {
storages := []SStorage{}
if len(zone) == 0 {
return nil, fmt.Errorf("zone params can not be empty")
}
resource := fmt.Sprintf("zones/%s/diskTypes", zone)
params := map[string]string{}
return storages, region.List(resource, params, maxResults, pageToken, &storages)
}
func (region *SRegion) GetStorage(id string) (*SStorage, error) {
storage := &SStorage{}
return storage, region.Get(id, storage)
}
func (storage *SStorage) GetId() string {
return getGlobalId(storage.SelfLink)
}
func (storage *SStorage) GetGlobalId() string {
return storage.GetId()
}
func (storage *SStorage) GetName() string {
return storage.Description
}
func (storage *SStorage) GetStatus() string {
return api.STORAGE_ONLINE
}
func (storage *SStorage) IsEmulated() bool {
return true
}
func (storage *SStorage) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (storage *SStorage) Refresh() error {
_storage, err := storage.zone.region.GetStorage(storage.SelfLink)
if err != nil {
return err
}
return jsonutils.Update(storage, _storage)
}
func (storage *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache {
return storage.zone.region.getStoragecache()
}
func (storage *SStorage) GetIZone() cloudprovider.ICloudZone {
return storage.zone
}
func (storage *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
disks, err := storage.zone.region.GetDisks(storage.zone.Name, storage.Name, 0, "")
if err != nil {
return nil, err
}
idisks := []cloudprovider.ICloudDisk{}
for i := range disks {
disks[i].storage = storage
idisks = append(idisks, &disks[i])
}
return idisks, nil
}
func (storage *SStorage) GetStorageType() string {
return storage.Name
}
func (storage *SStorage) GetMediumType() string {
return api.DISK_TYPE_SSD
}
func (storage *SStorage) GetCapacityMB() int64 {
return 0
}
func (storage *SStorage) GetStorageConf() jsonutils.JSONObject {
return jsonutils.Marshal(map[string]string{
"ValidDiskSize": storage.ValidDiskSize,
"DefaultDiskSizeGb": storage.DefaultDiskSizeGb,
})
}
func (storage *SStorage) GetEnabled() bool {
return true
}
func (storage *SStorage) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
return nil, cloudprovider.ErrNotFound
}
func (storage *SStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (storage *SStorage) GetMountPoint() string {
return ""
}
func (storage *SStorage) IsSysDiskStore() bool {
return storage.Name != api.STORAGE_GOOGLE_LOCAL_STORAGE
}
+123
View File
@@ -0,0 +1,123 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"context"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SStoragecache struct {
region *SRegion
iimages []cloudprovider.ICloudImage
}
func (cache *SStoragecache) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (cache *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", cache.region.client.providerId, cache.region.GetId())
}
func (cache *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", cache.region.client.providerName, cache.region.GetId())
}
func (cache *SStoragecache) GetStatus() string {
return "available"
}
func (cache *SStoragecache) Refresh() error {
return nil
}
func (cache *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", cache.region.client.providerId, cache.region.GetGlobalId())
}
func (cache *SStoragecache) IsEmulated() bool {
return true
}
func (cache *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
images, err := cache.region.fetchImages()
if err != nil {
return nil, err
}
iimages := []cloudprovider.ICloudImage{}
for i := range images {
images[i].storagecache = cache
iimages = append(iimages, &images[i])
}
return iimages, nil
}
func (cache *SStoragecache) GetIImageById(extId string) (cloudprovider.ICloudImage, error) {
image, err := cache.region.GetImage(extId)
if err != nil {
return nil, err
}
return image, nil
}
func (cache *SStoragecache) GetPath() string {
return ""
}
func (cache *SStoragecache) UploadImage(ctx context.Context, userCred mcclient.TokenCredential, image *cloudprovider.SImageCreateOption, isForce bool) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (cache *SStoragecache) CreateIImage(snapshoutId, imageName, osType, imageDesc string) (cloudprovider.ICloudImage, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (cache *SRegion) CheckBucket(bucketName string) (*oss.Bucket, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (cache *SRegion) CreateImage(snapshoutId, imageName, imageDesc string) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (cache *SStoragecache) DownloadImage(userCred mcclient.TokenCredential, imageId string, extId string, path string) (jsonutils.JSONObject, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (region *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
cache := &SStoragecache{region: region}
return []cloudprovider.ICloudStoragecache{cache}, nil
}
func (region *SRegion) getStoragecache() cloudprovider.ICloudStoragecache {
return &SStoragecache{region: region}
}
func (region *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
cache := region.getStoragecache()
if id == cache.GetGlobalId() {
return cache, nil
}
return nil, cloudprovider.ErrNotFound
}
+122
View File
@@ -0,0 +1,122 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SVpc struct {
multicloud.SVpc
globalnetwork *SGlobalNetwork
region *SRegion
}
func (vpc *SVpc) GetName() string {
return fmt.Sprintf("%s(%s)", vpc.globalnetwork.Name, vpc.region.Name)
}
func (vpc *SVpc) GetId() string {
return getGlobalId(vpc.globalnetwork.SelfLink)
}
func (vpc *SVpc) GetGlobalId() string {
return vpc.GetId()
}
func (vpc *SVpc) Refresh() error {
return nil
}
func (vpc *SVpc) GetStatus() string {
return api.VPC_STATUS_AVAILABLE
}
func (vpc *SVpc) Delete() error {
return cloudprovider.ErrNotSupported
}
func (vpc *SVpc) GetCidrBlock() string {
return ""
}
func (vpc *SVpc) GetIGlobalNetworkId() string {
return vpc.globalnetwork.GetGlobalId()
}
func (vpc *SVpc) IsEmulated() bool {
return false
}
func (vpc *SVpc) GetIsDefault() bool {
return false
}
func (vpc *SVpc) GetRegion() cloudprovider.ICloudRegion {
return vpc.region
}
func (vpc *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (vpc *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
firewalls, err := vpc.region.GetFirewalls(vpc.globalnetwork.SelfLink, 0, "")
if err != nil {
return nil, errors.Wrap(err, "GetFirewalls")
}
isecgroups := []cloudprovider.ICloudSecurityGroup{}
tags := []string{}
allInstance := false
for _, firewall := range firewalls {
if len(firewall.TargetServiceAccounts) > 0 {
secgroup := &SSecurityGroup{vpc: vpc, ServiceAccount: firewall.TargetServiceAccounts[0]}
isecgroups = append(isecgroups, secgroup)
} else if len(firewall.TargetTags) > 0 && !utils.IsInStringArray(firewall.TargetTags[0], tags) {
secgroup := &SSecurityGroup{vpc: vpc, Tag: firewall.TargetTags[0]}
tags = append(tags, firewall.TargetTags[0])
isecgroups = append(isecgroups, secgroup)
} else if !allInstance {
secgroup := &SSecurityGroup{vpc: vpc}
isecgroups = append(isecgroups, secgroup)
allInstance = true
}
}
return isecgroups, nil
}
func (vpc *SVpc) getWire() *SWire {
return &SWire{vpc: vpc}
}
func (vpc *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
wire := vpc.getWire()
return []cloudprovider.ICloudWire{wire}, nil
}
func (vpc *SVpc) GetIWireById(id string) (cloudprovider.ICloudWire, error) {
if id != vpc.getWire().GetGlobalId() {
return nil, cloudprovider.ErrNotFound
}
return &SWire{vpc: vpc}, nil
}
+96
View File
@@ -0,0 +1,96 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SWire struct {
vpc *SVpc
}
func (wire *SWire) GetId() string {
return wire.vpc.GetGlobalId()
}
func (wire *SWire) GetGlobalId() string {
return fmt.Sprintf("%s-%s", getGlobalId(wire.GetId()), wire.vpc.region.Name)
}
func (wire *SWire) GetName() string {
return wire.vpc.GetName()
}
func (wire *SWire) CreateINetwork(name string, cidr string, desc string) (cloudprovider.ICloudNetwork, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (wire *SWire) GetIVpc() cloudprovider.ICloudVpc {
return wire.vpc
}
func (wire *SWire) GetIZone() cloudprovider.ICloudZone {
return nil
}
func (wire *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) {
networks, err := wire.vpc.region.GetNetworks(wire.vpc.globalnetwork.SelfLink, 0, "")
if err != nil {
return nil, err
}
inetworks := []cloudprovider.ICloudNetwork{}
for i := range networks {
networks[i].wire = wire
inetworks = append(inetworks, &networks[i])
}
return inetworks, nil
}
func (wire *SWire) GetINetworkById(id string) (cloudprovider.ICloudNetwork, error) {
network, err := wire.vpc.region.GetNetwork(id)
if err != nil {
return nil, err
}
if network.Network != wire.vpc.globalnetwork.SelfLink {
return nil, cloudprovider.ErrNotFound
}
network.wire = wire
return network, nil
}
func (wire *SWire) GetBandwidth() int {
return 0
}
func (wire *SWire) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (wire *SWire) GetStatus() string {
return "available"
}
func (wire *SWire) IsEmulated() bool {
return false
}
func (wire *SWire) Refresh() error {
return nil
}
+125
View File
@@ -0,0 +1,125 @@
// Copyright 2019 Yunion
//
// 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.
package google
import (
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SZone struct {
region *SRegion
Description string
ID string
Kind string
Name string
Region string
SelfLink string
AvailableCpuPlatforms []string
Status string
}
func (region *SRegion) GetZone(id string) (*SZone, error) {
zone := &SZone{}
return zone, region.Get(id, zone)
}
func (region *SRegion) GetZones(regionId string, maxResults int, pageToken string) ([]SZone, error) {
zones := []SZone{}
params := map[string]string{}
if len(regionId) > 0 {
params["filter"] = fmt.Sprintf(`region="%s/regions/%s"`, region.GetUrlPrefixWithProjectId(), regionId)
}
resource := "zones"
return zones, region.List(resource, params, maxResults, pageToken, &zones)
}
func (zone *SZone) GetName() string {
return zone.Name
}
func (zone *SZone) GetGlobalId() string {
return zone.GetId()
}
func (zone *SZone) GetId() string {
return fmt.Sprintf("%s/%s", zone.region.GetGlobalId(), zone.Name)
}
func (zone *SZone) GetIHostById(hostId string) (cloudprovider.ICloudHost, error) {
if hostId != zone.getHost().GetGlobalId() {
return nil, cloudprovider.ErrNotFound
}
return &SHost{zone: zone}, nil
}
func (zone *SZone) getHost() *SHost {
return &SHost{zone: zone}
}
func (zone *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) {
host := zone.getHost()
return []cloudprovider.ICloudHost{host}, nil
}
func (zone *SZone) GetIRegion() cloudprovider.ICloudRegion {
return zone.region
}
func (zone *SZone) GetIStorageById(storageId string) (cloudprovider.ICloudStorage, error) {
storage, err := zone.region.GetStorage(storageId)
if err != nil {
return nil, err
}
storage.zone = zone
return storage, nil
}
func (zone *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
storages, err := zone.region.GetStorages(zone.Name, 0, "")
if err != nil {
return nil, err
}
istorages := []cloudprovider.ICloudStorage{}
for i := range storages {
storages[i].zone = zone
istorages = append(istorages, &storages[i])
}
return istorages, nil
}
func (zone *SZone) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (zone *SZone) IsEmulated() bool {
return true
}
func (zone *SZone) Refresh() error {
return nil
}
func (zone *SZone) GetStatus() string {
if zone.Status == "UP" {
return api.ZONE_ENABLE
}
return api.ZONE_SOLDOUT
}
@@ -145,6 +145,14 @@ func (self *SHuaweiProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (cli *SHuaweiProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (cli *SHuaweiProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SHuaweiProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(extId)
}
+2 -1
View File
@@ -20,7 +20,8 @@ import (
_ "yunion.io/x/onecloud/pkg/multicloud/aliyun/provider"
_ "yunion.io/x/onecloud/pkg/multicloud/aws/provider"
_ "yunion.io/x/onecloud/pkg/multicloud/azure/provider"
_ "yunion.io/x/onecloud/pkg/multicloud/esxi/provider" // private clouds
_ "yunion.io/x/onecloud/pkg/multicloud/esxi/provider" // private clouds
_ "yunion.io/x/onecloud/pkg/multicloud/google/provider" // public clouds
_ "yunion.io/x/onecloud/pkg/multicloud/huawei/provider"
_ "yunion.io/x/onecloud/pkg/multicloud/objectstore/ceph/provider"
_ "yunion.io/x/onecloud/pkg/multicloud/objectstore/provider"
@@ -114,6 +114,14 @@ func (self *SObjectStoreProvider) GetIRegions() []cloudprovider.ICloudRegion {
return nil
}
func (self *SObjectStoreProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (self *SObjectStoreProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SObjectStoreProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
return nil, cloudprovider.ErrNotSupported
}
@@ -170,6 +170,14 @@ func (self *SOpenStackProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (self *SOpenStackProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (self *SOpenStackProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SOpenStackProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(extId)
}
@@ -161,6 +161,14 @@ func (self *SQcloudProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (client *SQcloudProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (client *SQcloudProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SQcloudProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(id)
}
+40
View File
@@ -23,6 +23,46 @@ import (
type SRegion struct{}
func (r *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
return nil, fmt.Errorf("Not Implement GetIDiskById")
}
func (r *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
return nil, fmt.Errorf("Not Implement GetIHostById")
}
func (r *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
return nil, fmt.Errorf("Not Implement GetIHosts")
}
func (r *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
return nil, fmt.Errorf("Not Implement GetISnapshotById")
}
func (r *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return nil, fmt.Errorf("Not Implement GetISnapshots")
}
func (r *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
return nil, fmt.Errorf("Not Implement GetIStorageById")
}
func (r *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
return nil, fmt.Errorf("Not Implement GetIStoragecacheById")
}
func (r *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
return nil, fmt.Errorf("Not Implement GetIStoragecaches")
}
func (r *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
return nil, fmt.Errorf("Not Implement GetIStorages")
}
func (r *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
return nil, fmt.Errorf("Not Implement GetIVMById")
}
func (r *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput) (string, error) {
return "", fmt.Errorf("CreateSnapshotPolicy not implement")
}
@@ -149,6 +149,14 @@ func (self *SUcloudProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (cli *SUcloudProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (cli *SUcloudProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SUcloudProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(extId)
}
+4
View File
@@ -27,3 +27,7 @@ type SVpc struct {
func (self *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) {
return nil, fmt.Errorf("Not Implemented GetNatGateways")
}
func (self *SVpc) GetIGlobalNetworkId() string {
return ""
}
@@ -124,6 +124,14 @@ func (self *SZStackProvider) GetIRegions() []cloudprovider.ICloudRegion {
return self.client.GetIRegions()
}
func (cli *SZStackProvider) GetIGlobalnetworks() ([]cloudprovider.ICloudGlobalnetwork, error) {
return []cloudprovider.ICloudGlobalnetwork{}, nil
}
func (cli *SZStackProvider) GetIGlobalnetworkById(id string) (cloudprovider.ICloudGlobalnetwork, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SZStackProvider) GetIRegionById(extId string) (cloudprovider.ICloudRegion, error) {
return self.client.GetIRegionById(extId)
}