Files
cloudpods/pkg/compute/models/networkinterfacenetwork.go
2020-05-18 20:58:33 +08:00

232 lines
7.7 KiB
Go

// 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"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SNetworkinterfacenetworkManager struct {
db.SJointResourceBaseManager
}
var NetworkinterfacenetworkManager *SNetworkinterfacenetworkManager
func init() {
db.InitManager(func() {
NetworkinterfacenetworkManager = &SNetworkinterfacenetworkManager{
SJointResourceBaseManager: db.NewJointResourceBaseManager(
SNetworkinterfacenetwork{},
"networkinterfacenetworks_tbl",
"networkinterfacenetwork",
"networkinterfacenetworks",
NetworkInterfaceManager,
NetworkManager,
),
}
NetworkinterfacenetworkManager.SetVirtualObject(NetworkinterfacenetworkManager)
})
}
type SNetworkinterfacenetwork struct {
db.SJointResourceBase
Primary bool `nullable:"false" list:"user"`
IpAddr string `width:"16" charset:"ascii" nullable:"false" list:"user"`
NetworkinterfaceId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"` // Column(VARCHAR(36, charset='ascii'), nullable=False)
NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SNetworkinterfacenetworkManager) GetMasterFieldName() string {
return "networkinterface_id"
}
func (manager *SNetworkinterfacenetworkManager) GetSlaveFieldName() string {
return "network_id"
}
func (joint *SNetworkinterfacenetwork) Master() db.IStandaloneModel {
return db.JointMaster(joint)
}
func (joint *SNetworkinterfacenetwork) Slave() db.IStandaloneModel {
return db.JointSlave(joint)
}
func (manager *SNetworkinterfacenetworkManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsAdminAllowList(userCred, manager)
}
func (manager *SNetworkinterfacenetworkManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowCreate(userCred, manager)
}
func (manager *SNetworkinterfacenetworkManager) AllowListDescendent(ctx context.Context, userCred mcclient.TokenCredential, model db.IStandaloneModel, query jsonutils.JSONObject) bool {
return db.IsAdminAllowList(userCred, manager)
}
func (manager *SNetworkinterfacenetworkManager) AllowAttach(ctx context.Context, userCred mcclient.TokenCredential, master db.IStandaloneModel, slave db.IStandaloneModel) bool {
return db.IsAdminAllowCreate(userCred, manager)
}
func (self *SNetworkinterfacenetwork) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsAdminAllowGet(userCred, self)
}
func (self *SNetworkinterfacenetwork) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool {
return db.IsAdminAllowUpdate(userCred, self)
}
func (self *SNetworkinterfacenetwork) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowDelete(userCred, self)
}
func (self *SNetworkinterfacenetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
}
func (self *SNetworkinterfacenetwork) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
}
func (manager *SNetworkinterfacenetworkManager) SyncInterfaceAddresses(ctx context.Context, userCred mcclient.TokenCredential, networkinterface *SNetworkInterface, exts []cloudprovider.ICloudInterfaceAddress) compare.SyncResult {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, networkinterface.GetOwnerId()))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, networkinterface.GetOwnerId()))
syncResult := compare.SyncResult{}
dbResources, err := networkinterface.GetNetworks()
if err != nil {
return syncResult
}
removed := make([]SNetworkinterfacenetwork, 0)
commondb := make([]SNetworkinterfacenetwork, 0)
commonext := make([]cloudprovider.ICloudInterfaceAddress, 0)
added := make([]cloudprovider.ICloudInterfaceAddress, 0)
if err := compare.CompareSets(dbResources, exts, &removed, &commondb, &commonext, &added); err != nil {
return syncResult
}
for i := 0; i < len(removed); i += 1 {
err := removed[i].Delete(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
}
for i := 0; i < len(commondb); i += 1 {
err := commondb[i].SyncWithCloudkInterfaceAddress(ctx, userCred, commonext[i])
if err != nil {
syncResult.UpdateError(err)
continue
}
syncResult.Update()
}
for i := 0; i < len(added); i += 1 {
err := manager.newFromCloudInterfaceAddress(ctx, userCred, networkinterface, added[i])
if err != nil {
syncResult.AddError(err)
continue
}
syncResult.Add()
}
return syncResult
}
func (self *SNetworkinterfacenetwork) SyncWithCloudkInterfaceAddress(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterfaceAddress) error {
diff, err := db.UpdateWithLock(ctx, self, func() error {
self.Primary = ext.IsPrimary()
return nil
})
if err != nil {
return err
}
db.OpsLog.LogSyncUpdate(self, diff, userCred)
return nil
}
func (manager *SNetworkinterfacenetworkManager) newFromCloudInterfaceAddress(ctx context.Context, userCred mcclient.TokenCredential, networkinterface *SNetworkInterface, ext cloudprovider.ICloudInterfaceAddress) error {
address := SNetworkinterfacenetwork{
IpAddr: ext.GetIP(),
NetworkinterfaceId: networkinterface.Id,
Primary: ext.IsPrimary(),
}
address.SetModelManager(manager, &address)
networkId := ext.GetINetworkId()
_network, err := db.FetchByExternalId(NetworkManager, networkId)
if err != nil {
return errors.Wrapf(err, "newFromCloudInterfaceAddress.FetchByExternalId(%s)", networkId)
}
ipAddr, err := netutils.NewIPV4Addr(address.IpAddr)
if err != nil {
return errors.Wrap(err, "netutils.NewIPV4Addr")
}
network := _network.(*SNetwork)
if !network.IsAddressInRange(ipAddr) {
return fmt.Errorf("ip %s not in network %s(%s) range", address.IpAddr, network.Name, network.Id)
}
address.NetworkId = network.Id
err = manager.TableSpec().Insert(&address)
if err != nil {
return errors.Wrap(err, "TableSpec().Insert(&address)")
}
db.OpsLog.LogEvent(&address, db.ACT_CREATE, address.GetShortDesc(ctx), userCred)
return nil
}
func (self *SNetworkinterfacenetwork) GetNetwork() (*SNetwork, error) {
network, err := NetworkManager.FetchById(self.NetworkId)
if err != nil {
return nil, err
}
return network.(*SNetwork), nil
}
func (self *SNetworkinterfacenetwork) GetDetailJson() (jsonutils.JSONObject, error) {
network, err := self.GetNetwork()
if err != nil {
return nil, err
}
return jsonutils.Marshal(map[string]interface{}{
"network_id": self.NetworkId,
"ip_addr": self.IpAddr,
"primary": self.Primary,
"networkinterface_id": self.NetworkinterfaceId,
"network": network.Name,
}), nil
}