| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645 |
- // 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 (
- "context"
- "database/sql"
- "fmt"
- "sort"
- "strconv"
- "strings"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/httputils"
- randutil "yunion.io/x/pkg/util/rand"
- "yunion.io/x/pkg/util/regutils"
- "yunion.io/x/pkg/util/secrules"
- "yunion.io/x/pkg/util/sets"
- "yunion.io/x/pkg/utils"
- "yunion.io/x/sqlchemy"
- "yunion.io/x/onecloud/pkg/apis"
- billing_api "yunion.io/x/onecloud/pkg/apis/billing"
- api "yunion.io/x/onecloud/pkg/apis/compute"
- hostapi "yunion.io/x/onecloud/pkg/apis/host"
- "yunion.io/x/onecloud/pkg/cloudcommon/db"
- "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
- "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
- "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
- "yunion.io/x/onecloud/pkg/cloudcommon/validators"
- "yunion.io/x/onecloud/pkg/compute/models"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/mcclient"
- )
- type SKVMRegionDriver struct {
- SBaseRegionDriver
- }
- func init() {
- driver := SKVMRegionDriver{}
- models.RegisterRegionDriver(&driver)
- }
- func RunValidators(ctx context.Context, validators map[string]validators.IValidator, data *jsonutils.JSONDict, optional bool) error {
- for _, v := range validators {
- if optional {
- v.Optional(true)
- }
- if err := v.Validate(ctx, data); err != nil {
- return err
- }
- }
- return nil
- }
- func (self *SKVMRegionDriver) GetProvider() string {
- return api.CLOUD_PROVIDER_ONECLOUD
- }
- func (self *SKVMRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
- for i := range input.Rules {
- err := input.Rules[i].Check()
- if err != nil {
- return input, httperrors.NewInputParameterError("rule %d is invalid: %s", i, err)
- }
- }
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.LoadbalancerCreateInput) (*api.LoadbalancerCreateInput, error) {
- // find available networks
- var network *models.SNetwork = nil
- if len(input.NetworkId) > 0 {
- netObj, err := validators.ValidateModel(ctx, userCred, models.NetworkManager, &input.NetworkId)
- if err != nil {
- return nil, err
- }
- network = netObj.(*models.SNetwork)
- } else if len(input.VpcId) > 0 {
- vpcObj, err := validators.ValidateModel(ctx, userCred, models.VpcManager, &input.VpcId)
- if err != nil {
- return nil, err
- }
- vpc := vpcObj.(*models.SVpc)
- networks, err := vpc.GetNetworks()
- if err != nil {
- return nil, httperrors.NewGeneralError(err)
- }
- networksLen := len(networks)
- if networksLen > 0 {
- i := randutil.Intn(networksLen)
- j := (i + 1) % networksLen
- for {
- net := &networks[j]
- addrCount, err := net.GetFreeAddressCount()
- if err != nil {
- continue
- }
- if addrCount > 0 {
- network = net
- break
- }
- j = (j + 1) % networksLen
- if j == i {
- break
- }
- }
- }
- if network == nil {
- return nil, httperrors.NewBadRequestError("no usable network in vpc %s(%s)", vpc.Name, vpc.Id)
- }
- } else {
- return nil, httperrors.NewMissingParameterError("network_id")
- }
- if network.ServerType != api.NETWORK_TYPE_GUEST {
- return nil, httperrors.NewBadRequestError("only network type %q is allowed", api.NETWORK_TYPE_GUEST)
- }
- if len(input.ClusterId) > 0 {
- clusterObj, err := validators.ValidateModel(ctx, userCred, models.LoadbalancerClusterManager, &input.ClusterId)
- if err != nil {
- return nil, err
- }
- cluster := clusterObj.(*models.SLoadbalancerCluster)
- input.ZoneId = cluster.ZoneId
- if cluster.WireId != "" && cluster.WireId != network.WireId {
- return nil, httperrors.NewInputParameterError("cluster wire affiliation does not match network's: %s != %s",
- cluster.WireId, network.WireId)
- }
- } else {
- if len(input.ZoneId) == 0 {
- return nil, httperrors.NewMissingParameterError("zone_id")
- }
- clusters := models.LoadbalancerClusterManager.FindByZoneId(input.ZoneId)
- if len(clusters) == 0 {
- return nil, httperrors.NewInputParameterError("zone %s has no lbcluster", input.ZoneId)
- }
- var (
- wireMatched []*models.SLoadbalancerCluster
- wireNeutral []*models.SLoadbalancerCluster
- )
- for i := range clusters {
- c := &clusters[i]
- if c.WireId != "" {
- if c.WireId == network.WireId {
- wireMatched = append(wireMatched, c)
- }
- } else {
- wireNeutral = append(wireNeutral, c)
- }
- }
- var choices []*models.SLoadbalancerCluster
- if len(wireMatched) > 0 {
- choices = wireMatched
- } else if len(wireNeutral) > 0 {
- choices = wireNeutral
- } else {
- return nil, httperrors.NewInputParameterError("no viable lbcluster")
- }
- i := randutil.Intn(len(choices))
- input.ClusterId = choices[i].Id
- }
- input.NetworkType = api.LB_NETWORK_TYPE_VPC
- if input.VpcId == api.DEFAULT_VPC_ID {
- input.NetworkType = api.LB_NETWORK_TYPE_CLASSIC
- }
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendGroupData(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, input *api.LoadbalancerBackendGroupCreateInput) (*api.LoadbalancerBackendGroupCreateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateCreateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, lbbg *models.SLoadbalancerBackendGroup, input *api.LoadbalancerBackendCreateInput) (*api.LoadbalancerBackendCreateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateUpdateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, input *api.LoadbalancerBackendUpdateInput) (*api.LoadbalancerBackendUpdateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) IsSupportLoadbalancerListenerRuleRedirect() bool {
- return true
- }
- func (self *SKVMRegionDriver) ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.LoadbalancerListenerRuleCreateInput) (*api.LoadbalancerListenerRuleCreateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateUpdateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, input *api.LoadbalancerListenerRuleUpdateInput) (*api.LoadbalancerListenerRuleUpdateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential,
- ownerId mcclient.IIdentityProvider, input *api.LoadbalancerListenerCreateInput,
- lb *models.SLoadbalancer, lbbg *models.SLoadbalancerBackendGroup) (*api.LoadbalancerListenerCreateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential,
- lblis *models.SLoadbalancerListener, input *api.LoadbalancerListenerUpdateInput) (*api.LoadbalancerListenerUpdateInput, error) {
- /*
- certV := validators.NewModelIdOrNameValidator("certificate", "loadbalancercertificate", ownerId)
- tlsCipherPolicyV := validators.NewStringChoicesValidator("tls_cipher_policy", api.LB_TLS_CIPHER_POLICIES).Default(api.LB_TLS_CIPHER_POLICY_1_2)
- keyV := map[string]validators.IValidator{
- "send_proxy": validators.NewStringChoicesValidator("send_proxy", api.LB_SENDPROXY_CHOICES),
- "acl_status": aclStatusV,
- "acl_type": aclTypeV,
- "acl": aclV,
- "scheduler": validators.NewStringChoicesValidator("scheduler", api.LB_SCHEDULER_TYPES),
- "egress_mbps": validators.NewRangeValidator("egress_mbps", api.LB_MbpsMin, api.LB_MbpsMax),
- "client_request_timeout": validators.NewRangeValidator("client_request_timeout", 0, 600),
- "client_idle_timeout": validators.NewRangeValidator("client_idle_timeout", 0, 600),
- "backend_connect_timeout": validators.NewRangeValidator("backend_connect_timeout", 0, 180),
- "backend_idle_timeout": validators.NewRangeValidator("backend_idle_timeout", 0, 600),
- "sticky_session": validators.NewStringChoicesValidator("sticky_session", api.LB_BOOL_VALUES),
- "sticky_session_type": validators.NewStringChoicesValidator("sticky_session_type", api.LB_STICKY_SESSION_TYPES),
- "sticky_session_cookie": validators.NewRegexpValidator("sticky_session_cookie", regexp.MustCompile(`\w+`)),
- "sticky_session_cookie_timeout": validators.NewNonNegativeValidator("sticky_session_cookie_timeout"),
- "health_check": validators.NewStringChoicesValidator("health_check", api.LB_BOOL_VALUES),
- "health_check_type": models.LoadbalancerListenerManager.CheckTypeV(lblis.ListenerType),
- "health_check_domain": validators.NewDomainNameValidator("health_check_domain").AllowEmpty(true),
- "health_check_path": validators.NewURLPathValidator("health_check_path"),
- "health_check_http_code": validators.NewStringMultiChoicesValidator("health_check_http_code", api.LB_HEALTH_CHECK_HTTP_CODES).Sep(","),
- "health_check_rise": validators.NewRangeValidator("health_check_rise", 1, 1000),
- "health_check_fall": validators.NewRangeValidator("health_check_fall", 1, 1000),
- "health_check_timeout": validators.NewRangeValidator("health_check_timeout", 1, 300),
- "health_check_interval": validators.NewRangeValidator("health_check_interval", 1, 1000),
- "x_forwarded_for": validators.NewBoolValidator("x_forwarded_for"),
- "gzip": validators.NewBoolValidator("gzip"),
- "http_request_rate": validators.NewNonNegativeValidator("http_request_rate"),
- "http_request_rate_per_src": validators.NewNonNegativeValidator("http_request_rate_per_src"),
- "certificate": certV,
- "tls_cipher_policy": tlsCipherPolicyV,
- "enable_http2": validators.NewBoolValidator("enable_http2"),
- "redirect": redirectV,
- "redirect_code": redirectCodeV,
- "redirect_scheme": redirectSchemeV,
- "redirect_host": redirectHostV.AllowEmpty(true),
- "redirect_path": redirectPathV.AllowEmpty(true),
- }
- if err := RunValidators(keyV, data, true); err != nil {
- return nil, err
- }
- var (
- redirectType = redirectV.Value
- listenerType = lblis.ListenerType
- )
- if redirectType != api.LB_REDIRECT_OFF {
- if redirectType == api.LB_REDIRECT_RAW {
- scheme, host, path := redirectSchemeV.Value, redirectHostV.Value, redirectPathV.Value
- if (scheme == "" || scheme == listenerType) && host == "" && path == "" {
- return nil, httperrors.NewInputParameterError("redirect must have at least one of scheme, host, path changed")
- }
- }
- }
- // NOTE: it's okay we turn off redirect
- //
- // - scheduler have default value on creation
- // - backend_group_id is allowed to have unset value for http, https listener
- if err := models.LoadbalancerListenerManager.ValidateAcl(aclStatusV, aclTypeV, aclV, data, lblis.GetProviderName()); err != nil {
- return nil, err
- }
- {
- if backendGroup == nil {
- if lblis.ListenerType != api.LB_LISTENER_TYPE_HTTP &&
- lblis.ListenerType != api.LB_LISTENER_TYPE_HTTPS {
- return nil, httperrors.NewInputParameterError("non http listener must have backend group set")
- }
- } else if lbbg, ok := backendGroup.(*models.SLoadbalancerBackendGroup); ok && lbbg.LoadbalancerId != lblis.LoadbalancerId {
- return nil, httperrors.NewInputParameterError("backend group %s(%s) belongs to loadbalancer %s instead of %s",
- lbbg.Name, lbbg.Id, lbbg.LoadbalancerId, lblis.LoadbalancerId)
- }
- }
- */
- return input, nil
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerInstance(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, input *api.LoadbalancerCreateInput, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- _, err := db.Update(lb, func() error {
- // TODO support use reserved ip address
- req := &models.SLoadbalancerNetworkRequestData{
- Loadbalancer: lb,
- NetworkId: lb.NetworkId,
- Address: lb.Address,
- }
- // NOTE the small window when agents can see the ephemeral address
- ln, err := models.LoadbalancernetworkManager.NewLoadbalancerNetwork(ctx, userCred, req)
- if err != nil {
- log.Errorf("allocating loadbalancer network failed: %v, req: %#v", err, req)
- lb.Address = ""
- } else {
- lb.Address = ln.IpAddr
- }
- return nil
- })
- if err != nil {
- return nil, errors.Wrapf(err, "db.Update")
- }
- // bind eip
- eipAddr := ""
- if input.EipBw > 0 && len(input.EipId) == 0 {
- // create eip first
- eipPendingUsage := &models.SRegionQuota{Eip: 1}
- eipPendingUsage.SetKeys(lb.GetQuotaKeys())
- eip, err := models.ElasticipManager.NewEipForVMOnHost(ctx, userCred, &models.NewEipForVMOnHostArgs{
- Bandwidth: input.EipBw,
- BgpType: input.EipBgpType,
- ChargeType: input.EipChargeType,
- AutoDellocate: input.EipAutoDellocate,
- Loadbalancer: lb,
- PendingUsage: eipPendingUsage,
- })
- if err != nil {
- log.Errorf("NewEipForVMOnHost fail %s", err)
- quotas.CancelPendingUsage(ctx, userCred, eipPendingUsage, eipPendingUsage, false)
- } else {
- eipAddr = eip.IpAddr
- opts := api.ElasticipAssociateInput{
- InstanceId: lb.Id,
- InstanceExternalId: lb.ExternalId,
- InstanceType: api.EIP_ASSOCIATE_TYPE_LOADBALANCER,
- }
- err = eip.AllocateAndAssociateInstance(ctx, userCred, lb, opts, "")
- if err != nil {
- return nil, errors.Wrap(err, "AllocateAndAssociateInstance")
- }
- }
- } else if len(input.EipId) > 0 {
- _eip, err := models.ElasticipManager.FetchById(input.EipId)
- if err != nil {
- return nil, errors.Wrapf(err, "ElasticipManager.FetchById(%s)", input.EipId)
- }
- eip := _eip.(*models.SElasticip)
- err = eip.AssociateLoadbalancer(ctx, userCred, lb)
- if err != nil {
- return nil, errors.Wrapf(err, "eip.AssociateLoadbalancer")
- }
- eipAddr = eip.IpAddr
- }
- if len(eipAddr) > 0 {
- _, err = db.Update(lb, func() error {
- lb.Address = eipAddr
- lb.AddressType = api.LB_ADDR_TYPE_INTERNET
- return nil
- })
- if err != nil {
- return nil, errors.Wrap(err, "set loadbalancer address")
- }
- }
- return nil, nil
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestStartLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestStopLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestSyncstatusLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error {
- originStatus, _ := task.GetParams().GetString("origin_status")
- if utils.IsInStringArray(originStatus, []string{api.LB_STATUS_ENABLED, api.LB_STATUS_DISABLED}) {
- lb.SetStatus(ctx, userCred, originStatus, "")
- } else {
- lb.SetStatus(ctx, userCred, api.LB_STATUS_ENABLED, "")
- }
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *models.SLoadbalancer, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestUpdateLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestLoadbalancerAclSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error {
- lbacl.SetStatus(ctx, userCred, apis.STATUS_AVAILABLE, "")
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, lbacl *models.SLoadbalancerAcl, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancerCertificate(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestLoadbalancerCertificateSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, lbcert *models.SLoadbalancerCertificate, task taskman.ITask) error {
- lbcert.SetStatus(ctx, userCred, apis.STATUS_AVAILABLE, "")
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) GetBackendStatusForAdd() []string {
- return []string{api.VM_RUNNING, api.VM_READY}
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestStartLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestStopLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncstatusLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
- originStatus, _ := task.GetParams().GetString("origin_status")
- if utils.IsInStringArray(originStatus, []string{api.LB_STATUS_ENABLED, api.LB_STATUS_DISABLED}) {
- lblis.SetStatus(ctx, userCred, originStatus, "")
- } else {
- lblis.SetStatus(ctx, userCred, api.LB_STATUS_ENABLED, "")
- }
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, input *api.LoadbalancerListenerUpdateInput, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error) {
- if len(input.CidrBlock) > 0 && !utils.IsInStringArray(input.CidrBlock, []string{"192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12"}) {
- return input, httperrors.NewInputParameterError("Invalid cidr_block, want 192.168.0.0/16|10.0.0.0/8|172.16.0.0/12, got %s", input.CidrBlock)
- }
- if len(input.CidrBlock6) > 0 {
- input.CidrBlock6 = strings.ToLower(input.CidrBlock6)
- if !strings.HasPrefix(input.CidrBlock6, "fd") {
- return input, httperrors.NewInputParameterError("Invalid ipv6 cidr_block, %s outside of IPv6 private unicast address range fd00::/8", input.CidrBlock6)
- }
- }
- return input, nil
- }
- func (self *SKVMRegionDriver) RequestDeleteVpc(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, task taskman.ITask) error {
- task.ScheduleRun(nil)
- return nil
- }
- func (self *SKVMRegionDriver) GetEipDefaultChargeType() billing_api.TNetChargeType {
- return billing_api.NET_CHARGE_TYPE_BY_BANDWIDTH
- }
- func (self *SKVMRegionDriver) ValidateEipChargeType(chargeType billing_api.TNetChargeType) error {
- if chargeType != billing_api.NET_CHARGE_TYPE_BY_BANDWIDTH {
- return httperrors.NewInputParameterError("%s only supports eip charge type %q",
- self.GetProvider(), billing_api.NET_CHARGE_TYPE_BY_BANDWIDTH)
- }
- return nil
- }
- func (self *SKVMRegionDriver) ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error {
- if err := self.ValidateEipChargeType(input.ChargeType); err != nil {
- return err
- }
- var network *models.SNetwork
- if input.NetworkId != "" {
- _network, err := models.NetworkManager.FetchByIdOrName(ctx, userCred, input.NetworkId)
- if err != nil {
- if err == sql.ErrNoRows {
- return httperrors.NewResourceNotFoundError2("network", input.NetworkId)
- }
- return httperrors.NewGeneralError(err)
- }
- network = _network.(*models.SNetwork)
- input.BgpType = network.BgpType
- } else {
- q := models.NetworkManager.Query().
- Equals("server_type", api.NETWORK_TYPE_EIP).
- Equals("bgp_type", input.BgpType)
- var nets []models.SNetwork
- if err := db.FetchModelObjects(models.NetworkManager, q, &nets); err != nil {
- return err
- }
- eipNets := make([]models.SEipNetwork, 0)
- for i := range nets {
- net := &nets[i]
- cnt, _ := net.GetFreeAddressCount()
- if cnt > 0 {
- eipNets = append(eipNets, models.NewEipNetwork(net, userCred, userCred, cnt))
- }
- }
- if len(eipNets) == 0 {
- return httperrors.NewNotFoundError("no available eip network")
- }
- // prefer networks with identical project, domain, more free address, Id
- sort.Sort(models.SEipNetworks(eipNets))
- log.Debugf("eipnets: %s", jsonutils.Marshal(eipNets))
- network = eipNets[0].GetNetwork()
- input.NetworkId = network.Id
- }
- if network.ServerType != api.NETWORK_TYPE_EIP {
- return httperrors.NewInputParameterError("bad network type %q, want %q", network.ServerType, api.NETWORK_TYPE_EIP)
- }
- input.NetworkId = network.Id
- if len(input.IpAddr) > 0 {
- if !network.Contains(input.IpAddr) {
- return httperrors.NewInputParameterError("candidate %s out of range", input.IpAddr)
- }
- addrTable := network.GetUsedAddresses(ctx)
- if _, ok := addrTable[input.IpAddr]; ok {
- return httperrors.NewInputParameterError("requested ip %s is occupied!", input.IpAddr)
- }
- }
- vpc, _ := network.GetVpc()
- if vpc == nil {
- return httperrors.NewInputParameterError("failed to found vpc for network %s(%s)", network.Name, network.Id)
- }
- region, err := vpc.GetRegion()
- if err != nil {
- return err
- }
- if region.Id != input.CloudregionId {
- return httperrors.NewUnsupportOperationError("network %s(%s) does not belong to %s", network.Name, network.Id, self.GetProvider())
- }
- return nil
- }
- func (self *SKVMRegionDriver) ValidateSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot) error {
- storage := snapshot.GetStorage()
- if storage == nil {
- return httperrors.NewInternalServerError("Kvm snapshot missing storage ??")
- }
- return models.GetStorageDriver(storage.StorageType).ValidateSnapshotDelete(ctx, snapshot)
- }
- func (self *SKVMRegionDriver) RequestDeleteSnapshot(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error {
- storage := snapshot.GetStorage()
- if storage == nil {
- return httperrors.NewInternalServerError("Kvm snapshot missing storage ??")
- }
- return models.GetStorageDriver(storage.StorageType).RequestDeleteSnapshot(ctx, snapshot, task)
- }
- func (self *SKVMRegionDriver) RequestDeleteInstanceSnapshot(ctx context.Context, isp *models.SInstanceSnapshot, task taskman.ITask) error {
- snapshots, err := isp.GetSnapshots()
- if err != nil {
- return err
- }
- if len(snapshots) == 0 {
- task.SetStage("OnInstanceSnapshotDelete", nil)
- if isp.WithMemory && isp.MemoryFileHostId != "" && isp.MemoryFilePath != "" {
- // request delete memory snapshot
- host := models.HostManager.FetchHostById(isp.MemoryFileHostId)
- if host == nil {
- return errors.Errorf("Not found host by %q", isp.MemoryFileHostId)
- }
- header := task.GetTaskRequestHeader()
- url := fmt.Sprintf("%s/servers/memory-snapshot", host.ManagerUri)
- if _, _, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "DELETE", url, header, jsonutils.Marshal(&hostapi.GuestMemorySnapshotDeleteRequest{
- InstanceSnapshotId: isp.GetId(),
- Path: isp.MemoryFilePath,
- }), false); err != nil {
- return err
- }
- } else {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- return nil, nil
- })
- }
- return nil
- }
- params := jsonutils.NewDict()
- taskParams := task.GetParams()
- var deleteSnapshotTotalCnt int64 = 1
- if taskParams.Contains("snapshot_total_count") {
- deleteSnapshotTotalCnt, _ = taskParams.Int("snapshot_total_count")
- }
- deletedSnapshotCnt := deleteSnapshotTotalCnt - int64(len(snapshots))
- params.Set("del_snapshot_id", jsonutils.NewString(snapshots[0].Id))
- task.SetStage("OnKvmSnapshotDelete", params)
- err = snapshots[0].StartSnapshotDeleteTask(ctx, task.GetUserCred(), false, task.GetTaskId(), int(deleteSnapshotTotalCnt), int(deletedSnapshotCnt))
- if err != nil {
- return err
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteInstanceBackup(ctx context.Context, ib *models.SInstanceBackup, task taskman.ITask) error {
- backups, err := ib.GetBackups()
- if err != nil {
- return err
- }
- if len(backups) == 0 {
- task.SetStage("OnInstanceBackupDelete", nil)
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- return nil, nil
- })
- return nil
- }
- params := jsonutils.NewDict()
- params.Set("del_backup_id", jsonutils.NewString(backups[0].Id))
- task.SetStage("OnKvmDiskBackupDelete", params)
- forceDelete := jsonutils.QueryBoolean(task.GetParams(), "force_delete", false)
- err = backups[0].StartBackupDeleteTask(ctx, task.GetUserCred(), task.GetTaskId(), forceDelete)
- if err != nil {
- return err
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestResetToInstanceSnapshot(ctx context.Context, guest *models.SGuest, isp *models.SInstanceSnapshot, task taskman.ITask, params *jsonutils.JSONDict) error {
- jIsps, err := isp.GetInstanceSnapshotJointsByOrder(guest)
- if err != nil {
- return errors.Wrap(err, "GetInstanceSnapshotJointsByOrder")
- }
- diskIndexI64, err := params.Int("disk_index")
- if err != nil {
- return errors.Wrap(err, "get 'disk_index' from params")
- }
- diskIndex := int(diskIndexI64)
- if diskIndex >= len(jIsps) {
- task.SetStage("OnInstanceSnapshotReset", nil)
- withMem := jsonutils.QueryBoolean(params, "with_memory", false)
- if isp.WithMemory && withMem {
- // reset do memory snapshot
- host, err := guest.GetHost()
- if err != nil {
- return err
- }
- header := task.GetTaskRequestHeader()
- url := fmt.Sprintf("%s/servers/%s/memory-snapshot-reset", host.ManagerUri, guest.GetId())
- if _, _, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, jsonutils.Marshal(&hostapi.GuestMemorySnapshotResetRequest{
- InstanceSnapshotId: isp.GetId(),
- Path: isp.MemoryFilePath,
- Checksum: isp.MemoryFileChecksum,
- }), false); err != nil {
- return err
- }
- } else {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- return nil, nil
- })
- }
- return nil
- }
- isj := jIsps[diskIndex]
- params = jsonutils.NewDict()
- params.Set("disk_index", jsonutils.NewInt(int64(diskIndex)))
- task.SetStage("OnKvmDiskReset", params)
- disk, err := isj.GetSnapshotDisk()
- if err != nil {
- return errors.Wrapf(err, "Get %d snapshot disk", diskIndex)
- }
- err = disk.StartResetDisk(ctx, task.GetUserCred(), isj.SnapshotId, false, guest, task.GetTaskId())
- if err != nil {
- return errors.Wrap(err, "StartResetDisk")
- }
- return nil
- }
- func (self *SKVMRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
- _, err := storage.GetMasterHost()
- if err != nil {
- return errors.Wrapf(err, "storage.GetMasterHost")
- }
- return models.GetStorageDriver(storage.StorageType).ValidateCreateSnapshotData(ctx, userCred, disk, input)
- }
- func (self *SKVMRegionDriver) RequestCreateSnapshot(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error {
- storage := snapshot.GetStorage()
- if storage == nil {
- return httperrors.NewInternalServerError("Kvm snapshot missing storage ??")
- }
- return models.GetStorageDriver(storage.StorageType).RequestCreateSnapshot(ctx, snapshot, task)
- }
- func (self *SKVMRegionDriver) RequestCreateInstanceSnapshot(ctx context.Context, guest *models.SGuest, isp *models.SInstanceSnapshot, task taskman.ITask, params *jsonutils.JSONDict) error {
- disks, _ := guest.GetGuestDisks()
- diskIndexI64, err := params.Int("disk_index")
- if err != nil {
- return errors.Wrap(err, "get 'disk_index' from params")
- }
- diskIndex := int(diskIndexI64)
- if diskIndex >= len(disks) {
- task.SetStage("OnInstanceSnapshot", nil)
- if isp.WithMemory {
- // request do memory snapshot
- host, err := guest.GetHost()
- if err != nil {
- return err
- }
- header := task.GetTaskRequestHeader()
- url := fmt.Sprintf("%s/servers/%s/memory-snapshot", host.ManagerUri, guest.GetId())
- if _, _, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, jsonutils.Marshal(&hostapi.GuestMemorySnapshotRequest{
- InstanceSnapshotId: isp.GetId(),
- }), false); err != nil {
- return err
- }
- } else {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- return nil, nil
- })
- }
- return nil
- }
- snapshot, err := func() (*models.SSnapshot, error) {
- lockman.LockClass(ctx, models.SnapshotManager, "name")
- defer lockman.ReleaseClass(ctx, models.SnapshotManager, "name")
- snapshotName, err := db.GenerateName(ctx, models.SnapshotManager, task.GetUserCred(),
- fmt.Sprintf("%s-%s", isp.Name, randutil.String(8)))
- if err != nil {
- return nil, errors.Wrap(err, "Generate snapshot name")
- }
- return models.SnapshotManager.CreateSnapshot(
- ctx, task.GetUserCred(), api.SNAPSHOT_MANUAL, disks[diskIndex].DiskId,
- guest.Id, "", snapshotName, -1, false, "")
- }()
- if err != nil {
- return err
- }
- err = isp.InheritTo(ctx, task.GetUserCred(), snapshot)
- if err != nil {
- return errors.Wrapf(err, "unable to inherit from instance snapshot %s to snapshot %s", isp.GetId(), snapshot.GetId())
- }
- err = models.InstanceSnapshotJointManager.CreateJoint(ctx, isp.Id, snapshot.Id, int8(diskIndex))
- if err != nil {
- return err
- }
- params = jsonutils.NewDict()
- params.Set("disk_index", jsonutils.NewInt(int64(diskIndex)))
- params.Set(strconv.Itoa(diskIndex), jsonutils.NewString(snapshot.Id))
- task.SetStage("OnKvmDiskSnapshot", params)
- if err := snapshot.StartSnapshotCreateTask(ctx, task.GetUserCred(), nil, task.GetTaskId()); err != nil {
- return err
- }
- return nil
- }
- func (self *SKVMRegionDriver) SnapshotIsOutOfChain(disk *models.SDisk) bool {
- storage, _ := disk.GetStorage()
- return models.GetStorageDriver(storage.StorageType).SnapshotIsOutOfChain(disk)
- }
- func (self *SKVMRegionDriver) GetDiskResetParams(snapshot *models.SSnapshot) *jsonutils.JSONDict {
- params := jsonutils.NewDict()
- params.Set("snapshot_id", jsonutils.NewString(snapshot.Id))
- params.Set("out_of_chain", jsonutils.NewBool(snapshot.OutOfChain))
- params.Set("location", jsonutils.NewString(snapshot.Location))
- if len(snapshot.BackingDiskId) > 0 {
- params.Set("backing_disk_id", jsonutils.NewString(snapshot.BackingDiskId))
- }
- return params
- }
- func (self *SKVMRegionDriver) OnDiskReset(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, data jsonutils.JSONObject) error {
- if disk.DiskSize != snapshot.VirtualSize {
- _, err := db.Update(disk, func() error {
- disk.DiskSize = snapshot.VirtualSize
- return nil
- })
- if err != nil {
- return err
- }
- }
- storage, _ := disk.GetStorage()
- return models.GetStorageDriver(storage.StorageType).OnDiskReset(ctx, userCred, disk, snapshot, data)
- }
- func (self *SKVMRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error {
- task.SetStage("OnKvmSnapshotDelete", nil)
- task.ScheduleRun(data)
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncDiskStatus(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- storage, err := disk.GetStorage()
- if err != nil {
- return nil, errors.Wrapf(err, "disk.GetStorage")
- }
- host, err := storage.GetMasterHost()
- if err != nil {
- return nil, errors.Wrapf(err, "storage.GetMasterHost")
- }
- header := task.GetTaskRequestHeader()
- url := fmt.Sprintf("%s/disks/%s/%s/status", host.ManagerUri, storage.Id, disk.Id)
- _, res, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", url, header, nil, false)
- if err != nil {
- return nil, err
- }
- var diskStatus string
- originStatus, _ := task.GetParams().GetString("origin_status")
- status, _ := res.GetString("status")
- if status == api.DISK_EXIST {
- if utils.IsInArray(originStatus, []string{
- api.DISK_UNKNOWN,
- api.DISK_REBUILD_FAILED,
- api.DISK_ATTACHING,
- api.DISK_DETACHING,
- }) {
- diskStatus = api.DISK_READY
- } else {
- diskStatus = originStatus
- }
- } else {
- diskStatus = api.DISK_UNKNOWN
- }
- return nil, disk.SetStatus(ctx, userCred, diskStatus, "sync status")
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateInstanceBackup(ctx context.Context, guest *models.SGuest, ib *models.SInstanceBackup, task taskman.ITask, params *jsonutils.JSONDict) error {
- disks, _ := guest.GetGuestDisks()
- task.SetStage("OnKvmDisksSnapshot", params)
- for i := range disks {
- disk := disks[i]
- backup, err := func() (*models.SDiskBackup, error) {
- lockman.LockClass(ctx, models.DiskBackupManager, "name")
- defer lockman.ReleaseClass(ctx, models.DiskBackupManager, "name")
- diskBackupName, err := db.GenerateName(ctx, models.DiskBackupManager, task.GetUserCred(),
- fmt.Sprintf("%s-%s", ib.Name, randutil.String(8)))
- if err != nil {
- return nil, errors.Wrap(err, "Generate diskbackup name")
- }
- return models.DiskBackupManager.CreateBackup(ctx, task.GetUserCred(), disk.DiskId, ib.BackupStorageId, diskBackupName)
- }()
- if err != nil {
- return err
- }
- err = ib.InheritTo(ctx, task.GetUserCred(), backup)
- if err != nil {
- return errors.Wrapf(err, "unable to inherit from instance backup %s to backup %s", ib.GetId(), backup.GetId())
- }
- err = models.InstanceBackupJointManager.CreateJoint(ctx, ib.Id, backup.Id, int8(i))
- if err != nil {
- return err
- }
- taskParams := jsonutils.NewDict()
- taskParams.Set("only_snapshot", jsonutils.JSONTrue)
- if err := backup.StartBackupCreateTask(ctx, task.GetUserCred(), taskParams, task.GetTaskId()); err != nil {
- return err
- }
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestPackInstanceBackup(ctx context.Context, ib *models.SInstanceBackup, task taskman.ITask, packageName string) error {
- backupStorage, err := ib.GetBackupStorage()
- if err != nil {
- return errors.Wrap(err, "unable to get backupStorage")
- }
- backups, err := ib.GetBackups()
- if err != nil {
- return errors.Wrap(err, "unable to get backups")
- }
- host, err := models.HostManager.GetEnabledKvmHostForDiskBackup(&backups[0])
- if err != nil {
- return errors.Wrap(err, "GetEnabledKvmHostForDiskBackup")
- }
- backupIds := make([]string, len(backups))
- for i := range backupIds {
- backupIds[i] = backups[i].GetId()
- }
- metadata, err := ib.PackMetadata(ctx, task.GetUserCred())
- if err != nil {
- return errors.Wrap(err, "unable to PackMetadata")
- }
- url := fmt.Sprintf("%s/storages/pack-instance-backup", host.ManagerUri)
- body := jsonutils.NewDict()
- body.Set("package_name", jsonutils.NewString(packageName))
- body.Set("backup_storage_id", jsonutils.NewString(backupStorage.GetId()))
- accessInfo, err := backupStorage.GetAccessInfo()
- if err != nil {
- return errors.Wrap(err, "GetAccessInfo")
- }
- body.Set("backup_storage_access_info", jsonutils.Marshal(accessInfo))
- body.Set("backup_ids", jsonutils.Marshal(backupIds))
- body.Set("metadata", jsonutils.Marshal(metadata))
- header := task.GetTaskRequestHeader()
- _, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
- if err != nil {
- return errors.Wrap(err, "unable to pack instancebackup")
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestUnpackInstanceBackup(ctx context.Context, ib *models.SInstanceBackup, task taskman.ITask, packageName string, metadataOnly bool) error {
- log.Infof("RequestUnpackInstanceBackup")
- backupStorage, err := ib.GetBackupStorage()
- if err != nil {
- return errors.Wrap(err, "unable to get backupStorage")
- }
- host, err := models.HostManager.GetEnabledKvmHostForBackupStorage(backupStorage)
- if err != nil {
- return errors.Wrap(err, "unable to GetEnabledKvmHost")
- }
- url := fmt.Sprintf("%s/storages/unpack-instance-backup", host.ManagerUri)
- log.Infof("url: %s", url)
- body := jsonutils.NewDict()
- body.Set("package_name", jsonutils.NewString(packageName))
- body.Set("backup_storage_id", jsonutils.NewString(backupStorage.GetId()))
- accessInfo, err := backupStorage.GetAccessInfo()
- if err != nil {
- return errors.Wrap(err, "GetAccessInfo")
- }
- body.Set("backup_storage_access_info", jsonutils.Marshal(accessInfo))
- if metadataOnly {
- body.Set("metadata_only", jsonutils.JSONTrue)
- }
- header := task.GetTaskRequestHeader()
- _, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
- if err != nil {
- return errors.Wrap(err, "unable to pack instancebackup")
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncBackupStorageStatus(ctx context.Context, userCred mcclient.TokenCredential, bs *models.SBackupStorage, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- host, err := models.HostManager.GetEnabledKvmHostForBackupStorage(bs)
- if err != nil {
- return nil, errors.Wrap(err, "GetEnabledKvmHostForBackupStorage")
- }
- url := fmt.Sprintf("%s/storages/sync-backup-storage", host.ManagerUri)
- body := jsonutils.NewDict()
- body.Set("backup_storage_id", jsonutils.NewString(bs.GetId()))
- accessInfo, err := bs.GetAccessInfo()
- if err != nil {
- return nil, errors.Wrap(err, "GetAccessInfo")
- }
- body.Set("backup_storage_access_info", jsonutils.Marshal(accessInfo))
- header := task.GetTaskRequestHeader()
- _, res, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
- if err != nil {
- return nil, err
- }
- status, _ := res.GetString("status")
- reason, _ := res.GetString("reason")
- return nil, bs.SetStatus(ctx, userCred, status, reason)
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncInstanceBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, ib *models.SInstanceBackup, task taskman.ITask) error {
- originStatus, _ := task.GetParams().GetString("origin_status")
- if utils.IsInStringArray(originStatus, []string{
- api.INSTANCE_BACKUP_STATUS_CREATING,
- api.INSTANCE_BACKUP_STATUS_DELETING,
- // api.INSTANCE_BACKUP_STATUS_RECOVERY,
- api.INSTANCE_BACKUP_STATUS_PACK,
- api.INSTANCE_BACKUP_STATUS_CREATING_FROM_PACKAGE,
- api.INSTANCE_BACKUP_STATUS_SAVING,
- api.INSTANCE_BACKUP_STATUS_SNAPSHOT,
- }) {
- err := ib.SetStatus(ctx, userCred, originStatus, "sync status")
- if err != nil {
- return err
- }
- task.SetStageComplete(ctx, nil)
- return nil
- }
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- task.SetStage("OnKvmBackupSyncstatus", nil)
- backups, err := ib.GetBackups()
- if err != nil {
- return nil, errors.Wrap(err, "unable to get backups")
- }
- for i := range backups {
- params := jsonutils.NewDict()
- params.Add(jsonutils.NewString(backups[i].GetStatus()), "origin_status")
- task, err := taskman.TaskManager.NewTask(ctx, "DiskBackupSyncstatusTask", &backups[i], userCred, params, task.GetTaskId(), "", nil)
- if err != nil {
- return nil, err
- }
- task.ScheduleRun(nil)
- }
- return nil, nil
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncDiskBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, backup *models.SDiskBackup, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- originStatus, _ := task.GetParams().GetString("origin_status")
- if utils.IsInStringArray(originStatus, []string{api.BACKUP_STATUS_CREATING, api.BACKUP_STATUS_SNAPSHOT, api.BACKUP_STATUS_SAVING, api.BACKUP_STATUS_CLEANUP_SNAPSHOT, api.BACKUP_STATUS_DELETING}) {
- return nil, backup.SetStatus(ctx, userCred, originStatus, "sync status")
- }
- backupStorage, err := backup.GetBackupStorage()
- if err != nil {
- return nil, errors.Wrap(err, "unable to get backupStorage")
- }
- /*storage, _ := backup.GetStorage()
- var host *models.SHost
- if storage != nil {
- host, _ = storage.GetMasterHost()
- }
- if host == nil {
- host, err = models.HostManager.GetEnabledKvmHost()
- if err != nil {
- return nil, errors.Wrap(err, "unable to GetEnabledKvmHost")
- }
- }*/
- host, err := models.HostManager.GetEnabledKvmHostForDiskBackup(backup)
- if err != nil {
- return nil, errors.Wrap(err, "GetEnabledKvmHostForDiskBackup")
- }
- log.Infof("host: %s, ManagerUri: %s", host.GetId(), host.ManagerUri)
- url := fmt.Sprintf("%s/storages/sync-backup", host.ManagerUri)
- body := jsonutils.NewDict()
- body.Set("backup_id", jsonutils.NewString(backup.GetId()))
- body.Set("backup_storage_id", jsonutils.NewString(backupStorage.GetId()))
- accessInfo, err := backupStorage.GetAccessInfo()
- if err != nil {
- return nil, errors.Wrap(err, "GetAccessInfo")
- }
- body.Set("backup_storage_access_info", jsonutils.Marshal(accessInfo))
- header := task.GetTaskRequestHeader()
- _, res, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
- if err != nil {
- return nil, err
- }
- var backupStatus string
- status, _ := res.GetString("status")
- if status == api.BACKUP_EXIST {
- backupStatus = api.BACKUP_STATUS_READY
- } else {
- backupStatus = api.BACKUP_STATUS_UNKNOWN
- }
- return nil, backup.SetStatus(ctx, userCred, backupStatus, "sync status")
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncSnapshotStatus(ctx context.Context, userCred mcclient.TokenCredential, snapshot *models.SSnapshot, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- storage := snapshot.GetStorage()
- host, err := storage.GetMasterHost()
- if err != nil {
- return nil, errors.Wrapf(err, "storage.GetMasterHost")
- }
- header := task.GetTaskRequestHeader()
- url := fmt.Sprintf("%s/snapshots/%s/%s/%s/status", host.ManagerUri, storage.Id, snapshot.DiskId, snapshot.Id)
- _, res, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", url, header, nil, false)
- if err != nil {
- return nil, err
- }
- var snapshotStatus string
- originStatus, _ := task.GetParams().GetString("origin_status")
- status, _ := res.GetString("status")
- if status == api.SNAPSHOT_EXIST {
- if originStatus == api.SNAPSHOT_UNKNOWN {
- snapshotStatus = api.SNAPSHOT_READY
- } else {
- snapshotStatus = originStatus
- }
- } else {
- snapshotStatus = api.SNAPSHOT_UNKNOWN
- }
- return nil, snapshot.SetStatus(ctx, userCred, snapshotStatus, "sync status")
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestAssociateEipForNAT(ctx context.Context, userCred mcclient.TokenCredential, nat *models.SNatGateway, eip *models.SElasticip, task taskman.ITask) error {
- return errors.Wrapf(cloudprovider.ErrNotSupported, "RequestAssociateEipForNAT")
- }
- func (self *SKVMRegionDriver) ValidateCacheSecgroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *models.SSecurityGroup, vpc *models.SVpc, classic bool) error {
- return errors.Wrap(httperrors.ErrNotSupported, "No need to cache secgroup for onecloud region")
- }
- func (self *SKVMRegionDriver) ValidateCreateElasticcacheData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.ElasticcacheCreateInput) (*api.ElasticcacheCreateInput, error) {
- return input, httperrors.NewNotSupportedError("Not support create elasticcache")
- }
- func (self *SKVMRegionDriver) RequestRestartElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestSyncElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestChangeElasticcacheSpec(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestSetElasticcacheMaintainTime(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheChangeSpec(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestUpdateElasticcacheAuthMode(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestUpdateElasticcacheSecgroups(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheSetMaintainTime(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheAllocatePublicConnection(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheReleasePublicConnection(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheFlushInstance(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheUpdateInstanceParameters(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheUpdateBackupPolicy(ctx context.Context, userCred mcclient.TokenCredential, ec *models.SElasticcache, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) ValidateCreateElasticcacheAccountData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
- return nil, nil
- }
- func (self *SKVMRegionDriver) ValidateCreateElasticcacheAclData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
- return nil, nil
- }
- func (self *SKVMRegionDriver) AllowCreateElasticcacheBackup(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, elasticcache *models.SElasticcache) error {
- return fmt.Errorf("not support create kvm elastic cache backup")
- }
- func (self *SKVMRegionDriver) ValidateCreateElasticcacheBackupData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
- return nil, nil
- }
- func (self *SKVMRegionDriver) RequestCreateElasticcacheAccount(ctx context.Context, userCred mcclient.TokenCredential, elasticcacheAccount *models.SElasticcacheAccount, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateElasticcacheAcl(ctx context.Context, userCred mcclient.TokenCredential, elasticcacheAcl *models.SElasticcacheAcl, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateElasticcacheBackup(ctx context.Context, userCred mcclient.TokenCredential, elasticcacheBackup *models.SElasticcacheBackup, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteElasticcacheAccount(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAccount, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteElasticcacheAcl(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAcl, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestDeleteElasticcacheBackup(ctx context.Context, userCred mcclient.TokenCredential, eb *models.SElasticcacheBackup, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheAccountResetPassword(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAccount, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheAclUpdate(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAcl, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) RequestElasticcacheBackupRestoreInstance(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheBackup, task taskman.ITask) error {
- return nil
- }
- func (self *SKVMRegionDriver) AllowUpdateElasticcacheAuthMode(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, elasticcache *models.SElasticcache) error {
- return fmt.Errorf("not support update kvm elastic cache auth_mode")
- }
- func (self *SKVMRegionDriver) RequestSyncBucketStatus(ctx context.Context, userCred mcclient.TokenCredential, bucket *models.SBucket, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- iBucket, err := bucket.GetIBucket(ctx)
- if err != nil {
- return nil, errors.Wrap(err, "bucket.GetIBucket")
- }
- return nil, bucket.SetStatus(ctx, userCred, iBucket.GetStatus(), "syncstatus")
- })
- return nil
- }
- func (self *SKVMRegionDriver) IsSupportedElasticcacheSecgroup() bool {
- return false
- }
- func (self *SKVMRegionDriver) GetMaxElasticcacheSecurityGroupCount() int {
- return 0
- }
- func (self *SKVMRegionDriver) RequestDeleteBackup(ctx context.Context, backup *models.SDiskBackup, task taskman.ITask) error {
- backupStorage, err := backup.GetBackupStorage()
- if err != nil {
- return errors.Wrap(err, "unable to get backupStorage")
- }
- host, err := models.HostManager.GetEnabledKvmHostForDiskBackup(backup)
- if err != nil {
- return errors.Wrap(err, "GetEnabledKvmHostForDiskBackup")
- }
- url := fmt.Sprintf("%s/storages/delete-backup", host.ManagerUri)
- body := jsonutils.NewDict()
- body.Set("backup_id", jsonutils.NewString(backup.GetId()))
- body.Set("backup_storage_id", jsonutils.NewString(backupStorage.GetId()))
- accessInfo, err := backupStorage.GetAccessInfo()
- if err != nil {
- return errors.Wrap(err, "GetAccessInfo")
- }
- body.Set("backup_storage_access_info", jsonutils.Marshal(accessInfo))
- header := task.GetTaskRequestHeader()
- _, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
- if err != nil {
- return errors.Wrap(err, "unable to backup")
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateBackup(ctx context.Context, backup *models.SDiskBackup, snapshotId string, task taskman.ITask) error {
- backupStorage, err := backup.GetBackupStorage()
- if err != nil {
- return errors.Wrap(err, "unable to get backupStorage")
- }
- disk, err := backup.GetDisk()
- if err != nil {
- return errors.Wrap(err, "unable to get disk")
- }
- guest := disk.GetGuest()
- if guest == nil {
- return errors.Wrap(err, "unable to get guest")
- }
- storage, err := disk.GetStorage()
- if err != nil {
- return errors.Wrap(err, "unable to get storage")
- }
- snapshotObj, err := models.SnapshotManager.FetchById(snapshotId)
- if err != nil {
- return errors.Wrap(err, "fetch snapshot")
- }
- snapshot := snapshotObj.(*models.SSnapshot)
- host, _ := guest.GetHost()
- url := fmt.Sprintf("%s/disks/%s/backup/%s", host.ManagerUri, storage.Id, disk.Id)
- body := jsonutils.NewDict()
- body.Set("snapshot_id", jsonutils.NewString(snapshotId))
- if snapshot.Location != "" {
- body.Set("snapshot_location", jsonutils.NewString(snapshot.Location))
- }
- body.Set("backup_id", jsonutils.NewString(backup.GetId()))
- body.Set("backup_storage_id", jsonutils.NewString(backupStorage.GetId()))
- accessInfo, err := backupStorage.GetAccessInfo()
- if err != nil {
- return errors.Wrap(err, "GetAccessInfo")
- }
- body.Set("backup_storage_access_info", jsonutils.Marshal(accessInfo))
- if len(backup.EncryptKeyId) > 0 {
- body.Set("encrypt_key_id", jsonutils.NewString(backup.EncryptKeyId))
- }
- header := task.GetTaskRequestHeader()
- _, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
- if err != nil {
- return errors.Wrap(err, "unable to backup")
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestAssociateEip(ctx context.Context, userCred mcclient.TokenCredential, eip *models.SElasticip, input api.ElasticipAssociateInput, obj db.IStatusStandaloneModel, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- if err := eip.AssociateInstance(ctx, userCred, input.InstanceType, obj); err != nil {
- return nil, errors.Wrapf(err, "associate eip %s(%s) to %s %s(%s)", eip.Name, eip.Id, obj.Keyword(), obj.GetName(), obj.GetId())
- }
- switch input.InstanceType {
- case api.EIP_ASSOCIATE_TYPE_SERVER:
- err := self.requestAssociateEipWithServer(ctx, userCred, eip, input, obj, task)
- if err != nil {
- return nil, err
- }
- case api.EIP_ASSOCIATE_TYPE_INSTANCE_GROUP:
- err := self.requestAssociateEipWithInstanceGroup(ctx, userCred, eip, input, obj, task)
- if err != nil {
- return nil, err
- }
- case api.EIP_ASSOCIATE_TYPE_LOADBALANCER:
- err := self.requestAssociateEipWithLoadbalancer(ctx, userCred, eip, input, obj, task)
- if err != nil {
- return nil, err
- }
- default:
- return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "instance type %s", input.InstanceType)
- }
- if err := eip.SetStatus(ctx, userCred, api.EIP_STATUS_READY, api.EIP_STATUS_ASSOCIATE); err != nil {
- return nil, errors.Wrapf(err, "set eip status to %s", api.EIP_STATUS_READY)
- }
- return nil, nil
- })
- return nil
- }
- func (self *SKVMRegionDriver) requestAssociateEipWithServer(ctx context.Context, userCred mcclient.TokenCredential, eip *models.SElasticip, input api.ElasticipAssociateInput, obj db.IStatusStandaloneModel, task taskman.ITask) error {
- guest := obj.(*models.SGuest)
- hps := sets.NewString(api.HYPERVISOR_KVM, api.HYPERVISOR_POD)
- if !hps.Has(guest.GetHypervisor()) {
- return errors.Wrapf(cloudprovider.ErrNotSupported, "not support associate eip for hypervisor %s", guest.GetHypervisor())
- }
- lockman.LockObject(ctx, guest)
- defer lockman.ReleaseObject(ctx, guest)
- var guestnics []models.SGuestnetwork
- {
- netq := models.NetworkManager.Query().SubQuery()
- wirq := models.WireManager.Query().SubQuery()
- vpcq := models.VpcManager.Query().SubQuery()
- gneq := models.GuestnetworkManager.Query()
- q := gneq.Equals("guest_id", guest.Id).
- IsNullOrEmpty("eip_id")
- if len(input.IpAddr) > 0 {
- q = q.Equals("ip_addr", input.IpAddr)
- }
- q = q.Join(netq, sqlchemy.Equals(netq.Field("id"), gneq.Field("network_id")))
- q = q.Join(wirq, sqlchemy.Equals(wirq.Field("id"), netq.Field("wire_id")))
- q = q.Join(vpcq, sqlchemy.Equals(vpcq.Field("id"), wirq.Field("vpc_id")))
- q = q.Filter(sqlchemy.NotEquals(vpcq.Field("id"), api.DEFAULT_VPC_ID))
- if err := db.FetchModelObjects(models.GuestnetworkManager, q, &guestnics); err != nil {
- return errors.Wrapf(err, "db.FetchModelObjects")
- }
- if len(guestnics) == 0 {
- return errors.Errorf("guest has no nics to associate eip")
- }
- }
- guestnic := &guestnics[0]
- lockman.LockObject(ctx, guestnic)
- defer lockman.ReleaseObject(ctx, guestnic)
- if _, err := db.Update(guestnic, func() error {
- guestnic.EipId = eip.Id
- return nil
- }); err != nil {
- return errors.Wrapf(err, "set associated eip for guestnic %s (guest:%s, network:%s)",
- guestnic.Ifname, guestnic.GuestId, guestnic.NetworkId)
- }
- return nil
- }
- func (self *SKVMRegionDriver) requestAssociateEipWithInstanceGroup(ctx context.Context, userCred mcclient.TokenCredential, eip *models.SElasticip, input api.ElasticipAssociateInput, obj db.IStatusStandaloneModel, task taskman.ITask) error {
- group := obj.(*models.SGroup)
- lockman.LockObject(ctx, group)
- defer lockman.ReleaseObject(ctx, group)
- var groupnics []models.SGroupnetwork
- {
- gneq := models.GroupnetworkManager.Query()
- q := gneq.Equals("group_id", group.Id).
- IsNullOrEmpty("eip_id")
- if len(input.IpAddr) > 0 {
- q = q.Equals("ip_addr", input.IpAddr)
- }
- if err := db.FetchModelObjects(models.GroupnetworkManager, q, &groupnics); err != nil {
- return errors.Wrapf(err, "db.FetchModelObjects")
- }
- if len(groupnics) == 0 {
- return errors.Errorf("instance group has no nics to associate eip")
- }
- }
- groupnic := &groupnics[0]
- lockman.LockObject(ctx, groupnic)
- defer lockman.ReleaseObject(ctx, groupnic)
- if _, err := db.Update(groupnic, func() error {
- groupnic.EipId = eip.Id
- return nil
- }); err != nil {
- return errors.Wrapf(err, "set associated eip for groupnic %s/%s (guest:%s, network:%s)",
- groupnic.IpAddr, groupnic.Ip6Addr, groupnic.GroupId, groupnic.NetworkId)
- }
- return nil
- }
- func (self *SKVMRegionDriver) requestAssociateEipWithLoadbalancer(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- eip *models.SElasticip,
- input api.ElasticipAssociateInput,
- obj db.IStatusStandaloneModel,
- task taskman.ITask,
- ) error {
- lb := obj.(*models.SLoadbalancer)
- if _, err := db.Update(lb, func() error {
- lb.Address = eip.IpAddr
- lb.AddressType = api.LB_ADDR_TYPE_INTERNET
- return nil
- }); err != nil {
- return errors.Wrap(err, "set loadbalancer address")
- }
- if err := eip.AssociateLoadbalancer(ctx, userCred, lb); err != nil {
- return errors.Wrapf(err, "associate eip %s(%s) to loadbalancer %s(%s)", eip.Name, eip.Id, lb.Name, lb.Id)
- }
- if err := eip.SetStatus(ctx, userCred, api.EIP_STATUS_READY, api.EIP_STATUS_ASSOCIATE); err != nil {
- return errors.Wrapf(err, "set eip status to %s", api.EIP_STATUS_ALLOCATE)
- }
- return nil
- }
- func (self *SKVMRegionDriver) RequestCreateSecurityGroup(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- secgroup *models.SSecurityGroup,
- rules api.SSecgroupRuleResourceSet,
- ) error {
- _, err := db.Update(secgroup, func() error {
- secgroup.VpcId = ""
- return nil
- })
- if err != nil {
- return err
- }
- for _, r := range rules {
- rule := &models.SSecurityGroupRule{
- Priority: int(*r.Priority),
- Protocol: r.Protocol,
- Ports: r.Ports,
- Direction: r.Direction,
- CIDR: r.CIDR,
- Action: r.Action,
- Description: r.Description,
- }
- rule.SecgroupId = secgroup.Id
- models.SecurityGroupRuleManager.TableSpec().Insert(ctx, rule)
- }
- secgroup.SetStatus(ctx, userCred, api.SECGROUP_STATUS_READY, "")
- return nil
- }
- func (self *SKVMRegionDriver) RequestPrepareSecurityGroups(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, secgroups []models.SSecurityGroup, vpc *models.SVpc, callback func(ids []string) error, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestDeleteSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *models.SSecurityGroup, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
- return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
- return q.Equals("cloudregion_id", api.DEFAULT_REGION_ID)
- }, nil
- }
- func (self *SKVMRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
- if input.Priority != nil {
- if *input.Priority < 1 || *input.Priority > 100 {
- return nil, httperrors.NewInputParameterError("invalid priority %d", input.Priority)
- }
- }
- if input.Action != nil {
- if !utils.IsInStringArray(*input.Action, []string{string(secrules.SecurityRuleAllow), string(secrules.SecurityRuleDeny)}) {
- return nil, httperrors.NewInputParameterError("invalid action %s", *input.Action)
- }
- }
- if input.Protocol != nil {
- if !utils.IsInStringArray(*input.Protocol, []string{
- secrules.PROTO_ANY,
- secrules.PROTO_UDP,
- secrules.PROTO_TCP,
- secrules.PROTO_ICMP,
- }) {
- return nil, httperrors.NewInputParameterError("invalid protocol %s", *input.Protocol)
- }
- }
- if input.Ports != nil {
- rule := secrules.SecurityRule{}
- err := rule.ParsePorts(*input.Ports)
- if err != nil {
- return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
- }
- }
- if input.CIDR != nil && len(*input.CIDR) > 0 && !regutils.MatchCIDR(*input.CIDR) && !regutils.MatchIP4Addr(*input.CIDR) && !regutils.MatchCIDR6(*input.CIDR) && !regutils.MatchIP6Addr(*input.CIDR) {
- return nil, httperrors.NewInputParameterError("invalid cidr %s", *input.CIDR)
- }
- return input, nil
- }
- func (self *SKVMRegionDriver) ValidateCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, input *api.SSnapshotPolicyCreateInput) (*api.SSnapshotPolicyCreateInput, error) {
- return input, nil
- }
- func (self *SKVMRegionDriver) RequestCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
- sp.SetStatus(ctx, userCred, apis.STATUS_AVAILABLE, "")
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestDeleteSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
- return task.ScheduleRun(nil)
- }
- func (self *SKVMRegionDriver) RequestSnapshotPolicyBindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- disks, err := sp.GetUnbindDisks(diskIds)
- if err != nil {
- return nil, errors.Wrapf(err, "GetUnbindDisks")
- }
- ids := []string{}
- for _, disk := range disks {
- ids = append(ids, disk.Id)
- }
- return nil, sp.BindDisks(ctx, disks)
- })
- return nil
- }
- func (self *SKVMRegionDriver) RequestSnapshotPolicyUnbindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
- taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
- return nil, sp.UnbindDisks(diskIds)
- })
- return nil
- }
|