mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-06 21:52:54 +08:00
fix: 结构化network create list 参数
This commit is contained in:
60
pkg/apis/compute/cloudprovider.go
Normal file
60
pkg/apis/compute/cloudprovider.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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
|
||||
|
||||
type CloudproviderDetails struct {
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Brand string `json:"brand,omitempty"`
|
||||
Account string `json:"account,omitempty"`
|
||||
AccountId string `json:"account_id,omitempty"`
|
||||
Manager string `json:"manager,omitempty"`
|
||||
ManagerId string `json:"manager_id,omitempty"`
|
||||
ManagerProject string `json:"manager_project,omitempty"`
|
||||
ManagerProjectId string `json:"manager_project_id,omitempty"`
|
||||
ManagerDomain string `json:"manager_domain,omitempty"`
|
||||
ManagerDomainId string `json:"manager_domain_id,omitempty"`
|
||||
Region string `json:"region,omitempty"`
|
||||
RegionId string `json:"region_id,omitempty"`
|
||||
CloudregionId string `json:"cloudregion_id,omitempty"`
|
||||
RegionExternalId string `json:"region_external_id,omitempty"`
|
||||
RegionExtId string `json:"region_ext_id,omitempty"`
|
||||
Zone string `json:"zone,omitempty"`
|
||||
ZoneId string `json:"zone_id,omitempty"`
|
||||
ZoneExtId string `json:"zone_ext_id,omitempty"`
|
||||
CloudEnv string `json:"cloud_env,omitempty"`
|
||||
}
|
||||
|
||||
type CloudaccountListInput struct {
|
||||
// List objects belonging to the cloud provider
|
||||
Cloudprovider string `json:"cloudprovider"`
|
||||
|
||||
// List objects belonging to the cloud account
|
||||
Cloudaccount string `json:"cloudprovider"`
|
||||
|
||||
// List objects from the providers, choices:"OneCloud|VMware|Aliyun|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack|Google"
|
||||
Providers []string `json:"providers"`
|
||||
|
||||
// List objects belonging to brands
|
||||
Brands []string `json:"brands"`
|
||||
}
|
||||
|
||||
type CloudTypeListInput struct {
|
||||
// enum: public_cloud,private_cloud,on_premise
|
||||
CloudEnv string `json:"cloud_env"`
|
||||
|
||||
// List objects managed by external providers
|
||||
// default: false
|
||||
IsManaged bool `json:"is_managed"`
|
||||
}
|
||||
201
pkg/apis/compute/network.go
Normal file
201
pkg/apis/compute/network.go
Normal file
@@ -0,0 +1,201 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type NetworkListInput struct {
|
||||
apis.BaseListInput
|
||||
|
||||
apis.SharableVirtualResourceListInput
|
||||
|
||||
CloudaccountListInput
|
||||
CloudTypeListInput
|
||||
|
||||
Zones []string `json:"zones"`
|
||||
|
||||
Vpc string `json:"vpc"`
|
||||
Cloudregion string `json:"cloudregion"`
|
||||
Usable bool `json:"usable"`
|
||||
Host string `json:"host"`
|
||||
City string `json:"city"`
|
||||
}
|
||||
|
||||
type NetworkCreateInput struct {
|
||||
apis.Meta
|
||||
|
||||
IsSystem bool `json:"is_system"`
|
||||
|
||||
// description: network name
|
||||
// unique: true
|
||||
// required: true
|
||||
// example: test-network
|
||||
Name string `json:"name"`
|
||||
|
||||
// description: network description
|
||||
// required: false
|
||||
// example: test create network
|
||||
Description string `json:"description"`
|
||||
|
||||
// description: ip range of guest, if not set, you shoud set guest_ip_start,guest_ip_end and guest_ip_mask params
|
||||
// example: 10.168.222.1/24
|
||||
GuestIpPrefix string `json:"guest_ip_prefix"`
|
||||
|
||||
// description: ip range of guest ip start, if set guest_ip_prefix, this parameter will be useless
|
||||
// example: 10.168.222.1
|
||||
GuestIpStart string `json:"guest_ip_start"`
|
||||
|
||||
// description: ip range of guest ip end, if set guest_ip_prefix, this parameter will be useless
|
||||
// example: 10.168.222.100
|
||||
GuestIpEnd string `json:"guest_ip_end"`
|
||||
|
||||
// description: ip range of guest ip mask, if set guest_ip_prefix, this parameter will be useless
|
||||
// example: 24
|
||||
// maximum: 30
|
||||
// minimum: 12
|
||||
GuestIpMask int64 `json:"guest_ip_mask"`
|
||||
|
||||
IfnameHint string `json:"ifname_hint"`
|
||||
|
||||
// description: guest gateway
|
||||
// example: 192.168.222.1
|
||||
GuestGateway string `json:"guest_gateway"`
|
||||
|
||||
// description: guest dns
|
||||
// example: 114.114.114.114
|
||||
GuestDns string `json:"guest_dns"`
|
||||
|
||||
// description: guest dhcp
|
||||
// example: 192.168.222.1,192.168.222.4
|
||||
GuestDHCP string `json:"guest_dhcp"`
|
||||
|
||||
// swagger:ignore
|
||||
WireId string `json:"wire_id"`
|
||||
|
||||
// description: wire id or name
|
||||
Wire string `json:"wire"`
|
||||
|
||||
// description: zone id or name
|
||||
Zone string `json:"zone"`
|
||||
|
||||
// description: vpc id or name
|
||||
Vpc string `json:"vpc"`
|
||||
|
||||
// description: server type
|
||||
// enum: guest,baremetal,pxe,ipmi
|
||||
// default: guest
|
||||
ServerType string `json:"server_type"`
|
||||
}
|
||||
|
||||
type NetworkDetails struct {
|
||||
apis.Meta
|
||||
apis.SharableVirtualResourceDetails
|
||||
|
||||
CloudproviderDetails
|
||||
SNetwork
|
||||
Wire string `json:"wire"`
|
||||
Exit bool `json:"exit"`
|
||||
Ports int `json:"ports"`
|
||||
PortsUsed int `json:"ports_used"`
|
||||
Vnics int `json:"vnics"`
|
||||
BmVnics int `json:"bm_nics"`
|
||||
LbVnics int `json:"lb_vnics"`
|
||||
EipVnics int `json:"eip_vnics"`
|
||||
GroupVnics int `json:"group_vnics"`
|
||||
ReserveVnics int `json:"reserve_vnics"`
|
||||
Vpc string `json:"vpc"`
|
||||
VpcId string `json:"vpc_id"`
|
||||
VpcExtId string `json:"vpc_ext_id"`
|
||||
|
||||
Routes [][]string `json:"routes"`
|
||||
Schedtags []SchedtagShortDescDetails `json:"schedtags"`
|
||||
}
|
||||
|
||||
type NetworkReserveIpInput struct {
|
||||
apis.Meta
|
||||
|
||||
// description: reserved ip list
|
||||
// required: true
|
||||
// example: [10.168.222.131, 10.168.222.134]
|
||||
Ips []string `json:"ips"`
|
||||
|
||||
// description: the comment
|
||||
// example: reserve ip for test
|
||||
Notes string `json:"notes"`
|
||||
Status string `json:"status"`
|
||||
// description: The reserved cycle
|
||||
// required: false
|
||||
Duration string `json:"duration"`
|
||||
}
|
||||
|
||||
type NetworkReleaseReservedIpInput struct {
|
||||
apis.Meta
|
||||
|
||||
// description: IP to be released
|
||||
// required: true
|
||||
// example: 10.168.222.121
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
type NetworkPurgeInput struct {
|
||||
apis.Meta
|
||||
}
|
||||
|
||||
type NetworkMergeInput struct {
|
||||
apis.Meta
|
||||
|
||||
// description: network id or name to be merged
|
||||
// required: true
|
||||
// example: test-network
|
||||
Target string `json:"target"`
|
||||
}
|
||||
|
||||
type NetworkSplitInput struct {
|
||||
apis.Meta
|
||||
|
||||
// description: The middle - separated IP must belong to the network
|
||||
// required: true
|
||||
// example: 10.168.222.181
|
||||
SplitIp string `json:"split_ip"`
|
||||
|
||||
// description: another network name after split
|
||||
// required: false
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type NetworkTryCreateNetworkInput struct {
|
||||
apis.Meta
|
||||
|
||||
Ip string `json:"ip"`
|
||||
Mask int `json:"mask"`
|
||||
ServerType string `json:"server_type"`
|
||||
IsOnPremise bool `json:"is_on_premise"`
|
||||
}
|
||||
|
||||
type NetworkSyncInput struct {
|
||||
apis.Meta
|
||||
}
|
||||
|
||||
type NetworkStatusInput struct {
|
||||
apis.Meta
|
||||
|
||||
// description: network status
|
||||
// required: true
|
||||
// example: available
|
||||
// enum: available,unavailable
|
||||
Status string `json:"status"`
|
||||
}
|
||||
22
pkg/apis/compute/schedtag.go
Normal file
22
pkg/apis/compute/schedtag.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
|
||||
type SchedtagShortDescDetails struct {
|
||||
*apis.StandaloneResourceShortDescDetail
|
||||
Default string `json:"default"`
|
||||
}
|
||||
29
pkg/apis/modelbase.go
Normal file
29
pkg/apis/modelbase.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 apis
|
||||
|
||||
type ModelBaseDetails struct {
|
||||
CanDelete bool `json:"can_delete"`
|
||||
DeleteFailReason string `json:"delete_fail_reason"`
|
||||
CanUpdate bool `json:"can_update"`
|
||||
UpdateFailReason string `json:"update_fail_reason"`
|
||||
}
|
||||
|
||||
type ModelBaseShortDescDetail struct {
|
||||
ResName string `json:"res_name"`
|
||||
}
|
||||
|
||||
type ModelBaseListInput struct {
|
||||
}
|
||||
@@ -50,28 +50,6 @@ type BaseListInput struct {
|
||||
// Export field keys
|
||||
ExportKeys string `json:"export_keys"`
|
||||
|
||||
// TODO: support this tags
|
||||
// Tags []string `help:"Tags info, eg: hypervisor=aliyun, os_type=Linux, os_version" json:"-"`
|
||||
// UserTags []string `help:"UserTags info, eg: group=rd" json:"-"`
|
||||
// CloudTags []string `help:"CloudTags info, eg: price_key=cn-beijing" json:"-"`
|
||||
// List objects belonging to the cloud provider
|
||||
Manager string `json:"manager,omitempty"`
|
||||
// List objects belonging to the cloud account
|
||||
Account string `json:"account,omitempty"`
|
||||
// List objects from the provider, choices:"OneCloud|VMware|Aliyun|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack"
|
||||
Provider []string `json:"provider,omitempty"`
|
||||
// List objects belonging to a special brand
|
||||
Brand []string `json:"brand"`
|
||||
// Cloud environment, choices:"public|private|onpremise|private_or_onpremise"
|
||||
CloudEnv string `json:"cloud_env,omitempty"`
|
||||
// List objects belonging to public cloud
|
||||
PublicCloud *bool `json:"public_cloud"`
|
||||
// List objects belonging to private cloud
|
||||
PrivateCloud *bool `json:"private_cloud"`
|
||||
// List objects belonging to on premise infrastructures
|
||||
IsOnPremise *bool `json:"is_on_premise"`
|
||||
// List objects managed by external providers
|
||||
IsManaged *bool `json:"is_managed"`
|
||||
// Marker for pagination
|
||||
PagingMarker string `json:"paging_marker"`
|
||||
}
|
||||
|
||||
29
pkg/apis/sharablevirtualresource.go
Normal file
29
pkg/apis/sharablevirtualresource.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 apis
|
||||
|
||||
type SharedProject struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type SharableVirtualResourceDetails struct {
|
||||
SharedProjects []SharedProject `json:"shared_projects"`
|
||||
VirtualResourceDetails
|
||||
}
|
||||
|
||||
type SharableVirtualResourceListInput struct {
|
||||
StandaloneResourceListInput
|
||||
}
|
||||
29
pkg/apis/standaloneresource.go
Normal file
29
pkg/apis/standaloneresource.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 apis
|
||||
|
||||
type StandaloneResourceShortDescDetail struct {
|
||||
ModelBaseShortDescDetail
|
||||
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type StandaloneResourceListInput struct {
|
||||
ModelBaseListInput
|
||||
|
||||
Tags []string `json:"tags"`
|
||||
WithoutUserMeta bool `json:"without_user_meta"`
|
||||
}
|
||||
19
pkg/apis/virtualresource.go
Normal file
19
pkg/apis/virtualresource.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// 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 apis
|
||||
|
||||
type VirtualResourceDetails struct {
|
||||
ModelBaseDetails
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/object"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
@@ -121,6 +122,10 @@ func (manager *SModelBaseManager) ListItemFilter(ctx context.Context, q *sqlchem
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) ListItemFilterV2(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, input *apis.ModelBaseListInput) (*sqlchemy.SQuery, error) {
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) CustomizeFilterList(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*CustomizeListFilters, error) {
|
||||
return NewCustomizeListFilters(), nil
|
||||
}
|
||||
@@ -415,6 +420,10 @@ func (model *SModelBase) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
return desc
|
||||
}
|
||||
|
||||
func (model *SModelBase) GetShortDescV2(ctx context.Context) *apis.ModelBaseShortDescDetail {
|
||||
return &apis.ModelBaseShortDescDetail{ResName: model.Keyword()}
|
||||
}
|
||||
|
||||
// list hooks
|
||||
func (model *SModelBase) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := jsonutils.NewDict()
|
||||
@@ -426,6 +435,22 @@ func (model *SModelBase) AllowGetDetails(ctx context.Context, userCred mcclient.
|
||||
return false
|
||||
}
|
||||
|
||||
func (model *SModelBase) GetExtraDetailsV2(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, out *apis.ModelBaseDetails) error {
|
||||
out.CanDelete = true
|
||||
out.CanUpdate = true
|
||||
err := model.GetIModel().ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
out.CanDelete = false
|
||||
out.DeleteFailReason = err.Error()
|
||||
}
|
||||
err = model.GetIModel().ValidateUpdateCondition(ctx)
|
||||
if err != nil {
|
||||
out.CanUpdate = false
|
||||
out.UpdateFailReason = err.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SModelBase) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
|
||||
extra := jsonutils.NewDict()
|
||||
return getModelExtraDetails(model.GetIModel(), ctx, extra), nil
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -277,11 +278,33 @@ func (model *SSharableVirtualResourceBase) getMoreDetails(ctx context.Context, u
|
||||
return extra
|
||||
}
|
||||
|
||||
func (model *SSharableVirtualResourceBase) getMoreDetailsV2(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) []apis.SharedProject {
|
||||
out := []apis.SharedProject{}
|
||||
for _, project := range model.GetSharedProjects() {
|
||||
tenant, err := TenantCacheManager.FetchTenantByIdOrName(ctx, project)
|
||||
if err != nil {
|
||||
log.Errorf("failed fetch tenant by id %s", project)
|
||||
continue
|
||||
}
|
||||
out = append(out, apis.SharedProject{Id: tenant.GetId(), Name: tenant.GetName()})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (model *SSharableVirtualResourceBase) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := model.SVirtualResourceBase.GetCustomizeColumns(ctx, userCred, query)
|
||||
return model.getMoreDetails(ctx, userCred, query, extra)
|
||||
}
|
||||
|
||||
func (model *SSharableVirtualResourceBase) GetExtraDetailsV2(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, out *apis.SharableVirtualResourceDetails) error {
|
||||
err := model.SVirtualResourceBase.GetExtraDetailsV2(ctx, userCred, query, &out.VirtualResourceDetails)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.SharedProjects = model.getMoreDetailsV2(ctx, userCred, query)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SSharableVirtualResourceBase) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
|
||||
extra, err := model.SVirtualResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
if err != nil {
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -201,6 +202,55 @@ func (manager *SStandaloneResourceBaseManager) ListItemFilter(ctx context.Contex
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SStandaloneResourceBaseManager) ListItemFilterV2(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, input *apis.StandaloneResourceListInput) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SResourceBaseManager.ListItemFilterV2(ctx, q, userCred, &input.ModelBaseListInput)
|
||||
if err != nil {
|
||||
return q, err
|
||||
}
|
||||
|
||||
metadataView := Metadata.Query()
|
||||
for idx, tag := range input.Tags {
|
||||
tagInfo := strings.Split(tag, "=")
|
||||
key, value := tagInfo[0], ""
|
||||
if len(tagInfo) == 2 {
|
||||
value = tagInfo[1]
|
||||
}
|
||||
if idx == 0 {
|
||||
metadataView = metadataView.Equals("key", key)
|
||||
if len(value) > 0 {
|
||||
metadataView = metadataView.Equals("value", value)
|
||||
}
|
||||
} else {
|
||||
subMetataView := Metadata.Query().Equals("key", key)
|
||||
if len(value) > 0 {
|
||||
subMetataView = subMetataView.Equals("value", value)
|
||||
}
|
||||
sq := subMetataView.SubQuery()
|
||||
metadataView.Join(sq, sqlchemy.Equals(metadataView.Field("id"), sq.Field("id")))
|
||||
}
|
||||
metadatas := metadataView.SubQuery()
|
||||
fieldName := fmt.Sprintf("%s_id", manager.Keyword())
|
||||
metadataSQ := metadatas.Query(
|
||||
sqlchemy.REPLACE(fieldName, metadatas.Field("id"), manager.Keyword()+"::", ""),
|
||||
)
|
||||
sq := metadataSQ.Filter(sqlchemy.Like(metadatas.Field("id"), manager.Keyword()+"::%")).Distinct()
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sq))
|
||||
}
|
||||
|
||||
if input.WithoutUserMeta {
|
||||
metadatas := Metadata.Query().SubQuery()
|
||||
fieldName := fmt.Sprintf("%s_id", manager.Keyword())
|
||||
metadataSQ := metadatas.Query(
|
||||
sqlchemy.REPLACE(fieldName, metadatas.Field("id"), manager.Keyword()+"::", ""),
|
||||
)
|
||||
sq := metadataSQ.Filter(sqlchemy.Like(metadatas.Field("key"), USER_TAG_PREFIX+"%")).Distinct()
|
||||
|
||||
q.Filter(sqlchemy.NotIn(q.Field("id"), sq))
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) StandaloneModelManager() IStandaloneModelManager {
|
||||
return model.GetModelManager().(IStandaloneModelManager)
|
||||
}
|
||||
@@ -227,6 +277,14 @@ func (model *SStandaloneResourceBase) GetShortDesc(ctx context.Context) *jsonuti
|
||||
return desc
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) GetShortDescV2(ctx context.Context) *apis.StandaloneResourceShortDescDetail {
|
||||
desc := &apis.StandaloneResourceShortDescDetail{}
|
||||
desc.ModelBaseShortDescDetail = *model.SResourceBase.GetShortDescV2(ctx)
|
||||
desc.Name = model.GetName()
|
||||
desc.Id = model.GetId()
|
||||
return desc
|
||||
}
|
||||
|
||||
/*
|
||||
* userCred: optional
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
identityapi "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -313,6 +314,10 @@ func (model *SVirtualResourceBase) GetCustomizeColumns(ctx context.Context, user
|
||||
return model.getMoreDetails(ctx, userCred, query, extra)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) GetExtraDetailsV2(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, out *apis.VirtualResourceDetails) error {
|
||||
return model.SStandaloneResourceBase.GetExtraDetailsV2(ctx, userCred, query, &out.ModelBaseDetails)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
|
||||
extra, err := model.SStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
if err != nil {
|
||||
|
||||
@@ -198,6 +198,39 @@ func splitProviders(providers []string) (bool, []string) {
|
||||
return oneCloud, others
|
||||
}
|
||||
|
||||
func filterByProviderStrsV2(q *sqlchemy.SQuery, filterField string, subqFunc func() *sqlchemy.SQuery, fieldName string, providerStrs []string) *sqlchemy.SQuery {
|
||||
oneCloud, providers := splitProviders(providerStrs)
|
||||
sq := q
|
||||
if len(filterField) > 0 {
|
||||
sq = subqFunc()
|
||||
}
|
||||
filters := make([]sqlchemy.ICondition, 0)
|
||||
if len(providers) > 0 {
|
||||
account := CloudaccountManager.Query().SubQuery()
|
||||
providers := CloudproviderManager.Query().SubQuery()
|
||||
subq := providers.Query(providers.Field("id"))
|
||||
subq = subq.Join(account, sqlchemy.Equals(
|
||||
account.Field("id"), providers.Field("cloudaccount_id"),
|
||||
))
|
||||
subq = subq.Filter(sqlchemy.In(account.Field(fieldName), providerStrs))
|
||||
filters = append(filters, sqlchemy.In(sq.Field("manager_id"), subq.SubQuery()))
|
||||
}
|
||||
if oneCloud {
|
||||
filters = append(filters, sqlchemy.IsNullOrEmpty(sq.Field("manager_id")))
|
||||
}
|
||||
if len(filters) == 1 {
|
||||
sq = sq.Filter(filters[0])
|
||||
} else if len(filters) > 1 {
|
||||
sq = sq.Filter(sqlchemy.OR(filters...))
|
||||
}
|
||||
if len(filterField) == 0 {
|
||||
q = sq
|
||||
} else {
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
func filterByProviderStrs(q *sqlchemy.SQuery, queryDict *jsonutils.JSONDict, filterField string, subqFunc func() *sqlchemy.SQuery, fieldName string, providerStrs []string) *sqlchemy.SQuery {
|
||||
queryDict.Remove(fieldName)
|
||||
oneCloud, providers := splitProviders(providerStrs)
|
||||
@@ -233,6 +266,54 @@ func filterByProviderStrs(q *sqlchemy.SQuery, queryDict *jsonutils.JSONDict, fil
|
||||
return q
|
||||
}
|
||||
|
||||
func managedResourceFilterByAccountV2(q *sqlchemy.SQuery, input *api.CloudaccountListInput, filterField string, subqFunc func() *sqlchemy.SQuery) (*sqlchemy.SQuery, error) {
|
||||
|
||||
if len(input.Cloudprovider) > 0 {
|
||||
provider, err := CloudproviderManager.FetchByIdOrName(nil, input.Cloudprovider)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(CloudproviderManager.Keyword(), input.Cloudprovider)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
if len(filterField) == 0 {
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("manager_id"), provider.GetId()))
|
||||
} else {
|
||||
sq := subqFunc()
|
||||
sq = sq.Filter(sqlchemy.Equals(sq.Field("manager_id"), provider.GetId()))
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.Cloudaccount) > 0 {
|
||||
account, err := CloudaccountManager.FetchByIdOrName(nil, input.Cloudaccount)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(CloudaccountManager.Keyword(), input.Cloudaccount)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", account.GetId()).SubQuery()
|
||||
if len(filterField) == 0 {
|
||||
q = q.Filter(sqlchemy.In(q.Field("manager_id"), subq))
|
||||
} else {
|
||||
sq := subqFunc()
|
||||
sq = sq.Filter(sqlchemy.In(sq.Field("manager_id"), subq))
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.Providers) > 0 {
|
||||
q = filterByProviderStrsV2(q, filterField, subqFunc, "provider", input.Providers)
|
||||
}
|
||||
|
||||
if len(input.Brands) > 0 {
|
||||
q = filterByProviderStrsV2(q, filterField, subqFunc, "brand", input.Brands)
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func managedResourceFilterByAccount(q *sqlchemy.SQuery, query jsonutils.JSONObject, filterField string, subqFunc func() *sqlchemy.SQuery) (*sqlchemy.SQuery, error) {
|
||||
queryDict := query.(*jsonutils.JSONDict)
|
||||
|
||||
@@ -396,6 +477,61 @@ func managedResourceFilterByCloudType(q *sqlchemy.SQuery, query jsonutils.JSONOb
|
||||
return q
|
||||
}
|
||||
|
||||
func managedResourceFilterByCloudTypeV2(q *sqlchemy.SQuery, input *api.CloudTypeListInput, filterField string, subqFunc func() *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
|
||||
if input.CloudEnv == api.CLOUD_ENV_PUBLIC_CLOUD {
|
||||
if len(filterField) == 0 {
|
||||
q = q.Filter(sqlchemy.In(q.Field("manager_id"), CloudproviderManager.GetPublicProviderIdsQuery()))
|
||||
} else {
|
||||
sq := subqFunc()
|
||||
sq = sq.Filter(sqlchemy.In(sq.Field("manager_id"), CloudproviderManager.GetPublicProviderIdsQuery()))
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if input.CloudEnv == api.CLOUD_ENV_PRIVATE_CLOUD {
|
||||
if len(filterField) == 0 {
|
||||
q = q.Filter(sqlchemy.In(q.Field("manager_id"), CloudproviderManager.GetPrivateProviderIdsQuery()))
|
||||
} else {
|
||||
sq := subqFunc()
|
||||
sq = sq.Filter(sqlchemy.In(sq.Field("manager_id"), CloudproviderManager.GetPrivateProviderIdsQuery()))
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if input.CloudEnv == api.CLOUD_ENV_ON_PREMISE {
|
||||
if len(filterField) == 0 {
|
||||
q = q.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.In(q.Field("manager_id"), CloudproviderManager.GetOnPremiseProviderIdsQuery()),
|
||||
sqlchemy.IsNullOrEmpty(q.Field("manager_id")),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
sq := subqFunc()
|
||||
sq = sq.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.In(sq.Field("manager_id"), CloudproviderManager.GetOnPremiseProviderIdsQuery()),
|
||||
sqlchemy.IsNullOrEmpty(sq.Field("manager_id")),
|
||||
),
|
||||
)
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if input.IsManaged {
|
||||
if len(filterField) == 0 {
|
||||
q = q.Filter(sqlchemy.IsNotEmpty(q.Field("manager_id")))
|
||||
} else {
|
||||
sq := subqFunc()
|
||||
sq = sq.Filter(sqlchemy.IsNotEmpty(sq.Field("manager_id")))
|
||||
q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
return q
|
||||
}
|
||||
|
||||
type SCloudProviderInfo struct {
|
||||
Provider string `json:",omitempty"`
|
||||
Brand string `json:",omitempty"`
|
||||
@@ -409,6 +545,7 @@ type SCloudProviderInfo struct {
|
||||
ManagerDomainId string `json:",omitempty"`
|
||||
Region string `json:",omitempty"`
|
||||
RegionId string `json:",omitempty"`
|
||||
CloudregionId string `json:",omitempty"`
|
||||
RegionExternalId string `json:",omitempty"`
|
||||
RegionExtId string `json:",omitempty"`
|
||||
Zone string `json:",omitempty"`
|
||||
@@ -447,6 +584,58 @@ func fetchExternalId(extId string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func MakeCloudProviderInfoV2(region *SCloudregion, zone *SZone, provider *SCloudprovider) api.CloudproviderDetails {
|
||||
info := api.CloudproviderDetails{}
|
||||
|
||||
if zone != nil {
|
||||
info.Zone = zone.GetName()
|
||||
info.ZoneId = zone.GetId()
|
||||
}
|
||||
|
||||
if region != nil {
|
||||
info.Region = region.GetName()
|
||||
info.RegionId = region.GetId()
|
||||
info.CloudregionId = region.GetId()
|
||||
}
|
||||
|
||||
if provider != nil {
|
||||
info.Manager = provider.GetName()
|
||||
info.ManagerId = provider.GetId()
|
||||
|
||||
if len(provider.ProjectId) > 0 {
|
||||
info.ManagerProjectId = provider.ProjectId
|
||||
tc, err := db.TenantCacheManager.FetchTenantById(appctx.Background, provider.ProjectId)
|
||||
if err == nil {
|
||||
info.ManagerProject = tc.GetName()
|
||||
info.ManagerDomain = tc.Domain
|
||||
info.ManagerDomainId = tc.DomainId
|
||||
}
|
||||
}
|
||||
|
||||
account := provider.GetCloudaccount()
|
||||
info.Account = account.GetName()
|
||||
info.AccountId = account.GetId()
|
||||
|
||||
info.Provider = provider.Provider
|
||||
info.Brand = account.Brand
|
||||
info.CloudEnv = account.getCloudEnv()
|
||||
|
||||
if region != nil {
|
||||
info.RegionExternalId = region.ExternalId
|
||||
info.RegionExtId = fetchExternalId(region.ExternalId)
|
||||
if zone != nil {
|
||||
info.ZoneExtId = fetchExternalId(zone.ExternalId)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info.CloudEnv = api.CLOUD_ENV_ON_PREMISE
|
||||
info.Provider = api.CLOUD_PROVIDER_ONECLOUD
|
||||
info.Brand = api.CLOUD_PROVIDER_ONECLOUD
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func MakeCloudProviderInfo(region *SCloudregion, zone *SZone, provider *SCloudprovider) SCloudProviderInfo {
|
||||
info := SCloudProviderInfo{}
|
||||
|
||||
@@ -458,6 +647,7 @@ func MakeCloudProviderInfo(region *SCloudregion, zone *SZone, provider *SCloudpr
|
||||
if region != nil {
|
||||
info.Region = region.GetName()
|
||||
info.RegionId = region.GetId()
|
||||
info.CloudregionId = region.GetId()
|
||||
}
|
||||
|
||||
if provider != nil {
|
||||
|
||||
@@ -985,13 +985,51 @@ func (self *SNetwork) getMoreDetails(ctx context.Context, extra *jsonutils.JSOND
|
||||
return extra
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
|
||||
extra, err := self.SSharableVirtualResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
func (self *SNetwork) getMoreDetailsV2(ctx context.Context, out *api.NetworkDetails) {
|
||||
wire := self.GetWire()
|
||||
if wire != nil {
|
||||
out.Wire = wire.Name
|
||||
}
|
||||
out.Exit = false
|
||||
if self.IsExitNetwork() {
|
||||
out.Exit = true
|
||||
}
|
||||
out.Ports = self.GetPorts()
|
||||
out.PortsUsed, _ = self.GetTotalNicCount()
|
||||
|
||||
out.Vnics, _ = self.GetGuestnicsCount()
|
||||
out.BmVnics, _ = self.GetBaremetalNicsCount()
|
||||
out.LbVnics, _ = self.GetLoadbalancerIpsCount()
|
||||
out.EipVnics, _ = self.GetEipsCount()
|
||||
out.GroupVnics, _ = self.GetGroupNicsCount()
|
||||
out.ReserveVnics, _ = self.GetReservedNicsCount()
|
||||
|
||||
vpc := self.getVpc()
|
||||
if vpc != nil {
|
||||
out.Vpc = vpc.Name
|
||||
out.VpcId = vpc.Id
|
||||
out.VpcExtId = vpc.ExternalId
|
||||
out.CloudproviderDetails = vpc.getCloudProviderInfoV2()
|
||||
}
|
||||
if len(out.Zone) == 0 {
|
||||
zone := self.getZone()
|
||||
if zone != nil {
|
||||
out.Zone = zone.Name
|
||||
out.ZoneId = zone.Id
|
||||
}
|
||||
}
|
||||
out.Routes = self.GetRoutes()
|
||||
out.Schedtags = GetSchedtagsDetailsToResourceV2(self, ctx)
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*api.NetworkDetails, error) {
|
||||
out := &api.NetworkDetails{}
|
||||
err := self.SSharableVirtualResourceBase.GetExtraDetailsV2(ctx, userCred, query, &out.SharableVirtualResourceDetails)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extra = self.getMoreDetails(ctx, extra)
|
||||
return extra, nil
|
||||
self.getMoreDetailsV2(ctx, out)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
@@ -1004,35 +1042,24 @@ func (self *SNetwork) AllowPerformReserveIp(ctx context.Context, userCred mcclie
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "reserve-ip")
|
||||
}
|
||||
|
||||
func (self *SNetwork) PerformReserveIp(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ips, err := data.GetArray("ips")
|
||||
if err != nil {
|
||||
if data.Contains("ip") {
|
||||
ip, _ := data.Get("ip")
|
||||
ips = []jsonutils.JSONObject{ip}
|
||||
} else {
|
||||
return nil, httperrors.NewMissingParameterError("ips")
|
||||
}
|
||||
}
|
||||
notes, err := data.GetString("notes")
|
||||
if err != nil {
|
||||
// 预留IP
|
||||
// 预留的IP不会被调度使用
|
||||
func (self *SNetwork) PerformReserveIp(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkReserveIpInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.Ips) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("ips")
|
||||
}
|
||||
status, _ := data.GetString("status")
|
||||
|
||||
var duration time.Duration
|
||||
durationStr, _ := data.GetString("duration")
|
||||
if len(durationStr) > 0 {
|
||||
bc, err := billing.ParseBillingCycle(durationStr)
|
||||
if len(input.Duration) > 0 {
|
||||
bc, err := billing.ParseBillingCycle(input.Duration)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Duration %s invalid", durationStr)
|
||||
return nil, httperrors.NewInputParameterError("Duration %s invalid", input.Duration)
|
||||
}
|
||||
duration = bc.Duration()
|
||||
}
|
||||
|
||||
for _, ip := range ips {
|
||||
ipstr, _ := ip.GetString()
|
||||
err := self.reserveIpWithDurationAndStatus(ctx, userCred, ipstr, notes, duration, status)
|
||||
for _, ip := range input.Ips {
|
||||
err := self.reserveIpWithDurationAndStatus(ctx, userCred, ip, input.Notes, duration, input.Status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1070,14 +1097,14 @@ func (self *SNetwork) AllowPerformReleaseReservedIp(ctx context.Context, userCre
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "release-reserved-ip")
|
||||
}
|
||||
|
||||
func (self *SNetwork) PerformReleaseReservedIp(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ipstr, _ := data.GetString("ip")
|
||||
if len(ipstr) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("Reserved ip to release must be provided")
|
||||
// 释放预留IP
|
||||
func (self *SNetwork) PerformReleaseReservedIp(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkReleaseReservedIpInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.Ip) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("ip")
|
||||
}
|
||||
rip := ReservedipManager.getReservedIP(self, ipstr)
|
||||
rip := ReservedipManager.getReservedIP(self, input.Ip)
|
||||
if rip == nil {
|
||||
return nil, httperrors.NewInvalidStatusError("Address %s not reserved", ipstr)
|
||||
return nil, httperrors.NewInvalidStatusError("Address %s not reserved", input.Ip)
|
||||
}
|
||||
rip.Release(ctx, userCred, self)
|
||||
return nil, nil
|
||||
@@ -1142,59 +1169,51 @@ func (manager *SNetworkManager) newIfnameHint(hint string) (string, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
prefixStr, _ := data.GetString("guest_ip_prefix")
|
||||
var maskLen64 int64
|
||||
func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *api.NetworkCreateInput) (*jsonutils.JSONDict, error) {
|
||||
var err error
|
||||
var startIp, endIp netutils.IPV4Addr
|
||||
if len(prefixStr) > 0 {
|
||||
prefix, err := netutils.NewIPV4Prefix(prefixStr)
|
||||
if len(input.GuestIpPrefix) > 0 {
|
||||
prefix, err := netutils.NewIPV4Prefix(input.GuestIpPrefix)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("ip_prefix error: %s", err)
|
||||
}
|
||||
iprange := prefix.ToIPRange()
|
||||
startIp = iprange.StartIp().StepUp()
|
||||
endIp = iprange.EndIp().StepDown()
|
||||
maskLen64 = int64(prefix.MaskLen)
|
||||
input.GuestIpMask = int64(prefix.MaskLen)
|
||||
} else {
|
||||
ipStartStr, _ := data.GetString("guest_ip_start")
|
||||
ipEndStr, _ := data.GetString("guest_ip_end")
|
||||
startIp, err = netutils.NewIPV4Addr(ipStartStr)
|
||||
startIp, err = netutils.NewIPV4Addr(input.GuestIpStart)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Invalid start ip: %s %s", ipStartStr, err)
|
||||
return nil, httperrors.NewInputParameterError("Invalid start ip: %s %s", input.GuestIpStart, err)
|
||||
}
|
||||
endIp, err = netutils.NewIPV4Addr(ipEndStr)
|
||||
endIp, err = netutils.NewIPV4Addr(input.GuestIpEnd)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid end ip: %s %s", ipEndStr, err)
|
||||
return nil, httperrors.NewInputParameterError("invalid end ip: %s %s", input.GuestIpEnd, err)
|
||||
}
|
||||
if startIp > endIp {
|
||||
tmp := startIp
|
||||
startIp = endIp
|
||||
endIp = tmp
|
||||
}
|
||||
maskLen64, _ = data.Int("guest_ip_mask")
|
||||
}
|
||||
if !isValidMaskLen(maskLen64) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid masklen %d", maskLen64)
|
||||
input.GuestIpStart = startIp.String()
|
||||
input.GuestIpEnd = endIp.String()
|
||||
|
||||
if !isValidMaskLen(input.GuestIpMask) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid masklen %d", input.GuestIpMask)
|
||||
}
|
||||
data.Add(jsonutils.NewInt(maskLen64), "guest_ip_mask")
|
||||
data.Add(jsonutils.NewString(startIp.String()), "guest_ip_start")
|
||||
data.Add(jsonutils.NewString(endIp.String()), "guest_ip_end")
|
||||
|
||||
{
|
||||
hint, _ := data.GetString("ifname_hint")
|
||||
if hint == "" {
|
||||
hint, _ = data.GetString("name")
|
||||
if len(input.IfnameHint) == 0 {
|
||||
input.IfnameHint = input.Name
|
||||
}
|
||||
hint, err = manager.newIfnameHint(hint)
|
||||
input.IfnameHint, err = manager.newIfnameHint(input.IfnameHint)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError("cannot derive valid ifname hint: %v", err)
|
||||
}
|
||||
data.Set("ifname_hint", jsonutils.NewString(hint))
|
||||
}
|
||||
|
||||
for _, key := range []string{"guest_gateway", "guest_dns", "guest_dhcp"} {
|
||||
ipStr, _ := data.GetString(key)
|
||||
for key, ipStr := range map[string]string{"guest_gateway": input.GuestGateway, "guest_dns": input.GuestDns, "guest_dhcp": input.GuestDHCP} {
|
||||
if len(ipStr) > 0 {
|
||||
if key == "guest_dhcp" {
|
||||
ipList := strings.Split(ipStr, ",")
|
||||
@@ -1218,36 +1237,37 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
return nil, httperrors.NewInputParameterError("Conflict address space with existing networks")
|
||||
}
|
||||
|
||||
wireStr := jsonutils.GetAnyString(data, []string{"wire", "wire_id"})
|
||||
if len(wireStr) > 0 {
|
||||
wireObj, err := WireManager.FetchByIdOrName(userCred, wireStr)
|
||||
if len(input.WireId) > 0 {
|
||||
input.Wire = input.WireId
|
||||
}
|
||||
|
||||
if len(input.Wire) > 0 {
|
||||
wireObj, err := WireManager.FetchByIdOrName(userCred, input.Wire)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("wire %s not found", wireStr)
|
||||
return nil, httperrors.NewNotFoundError("wire %s not found", input.Wire)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query wire %s error %s", wireStr, err)
|
||||
return nil, httperrors.NewInternalServerError("query wire %s error %s", input.Wire, err)
|
||||
}
|
||||
}
|
||||
data.Add(jsonutils.NewString(wireObj.GetId()), "wire_id")
|
||||
input.WireId = wireObj.GetId()
|
||||
} else {
|
||||
zoneStr := jsonutils.GetAnyString(data, []string{"zone", "zone_id"})
|
||||
if len(zoneStr) > 0 {
|
||||
vpcStr := jsonutils.GetAnyString(data, []string{"vpc", "vpc_id"})
|
||||
if len(vpcStr) > 0 {
|
||||
zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zoneStr)
|
||||
if len(input.Zone) > 0 {
|
||||
if len(input.Vpc) > 0 {
|
||||
zoneObj, err := ZoneManager.FetchByIdOrName(userCred, input.Zone)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("zone %s not found", zoneStr)
|
||||
return nil, httperrors.NewNotFoundError("zone %s not found", input.Zone)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query zone %s error %s", zoneStr, err)
|
||||
return nil, httperrors.NewInternalServerError("query zone %s error %s", input.Zone, err)
|
||||
}
|
||||
}
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred, vpcStr)
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred, input.Vpc)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("vpc %s not found", vpcStr)
|
||||
return nil, httperrors.NewNotFoundError("vpc %s not found", input.Vpc)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query vpc %s error %s", vpcStr, err)
|
||||
return nil, httperrors.NewInternalServerError("query vpc %s error %s", input.Vpc, err)
|
||||
}
|
||||
}
|
||||
vpc := vpcObj.(*SVpc)
|
||||
@@ -1259,21 +1279,21 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
|
||||
// 华为云,ucloud wire zone_id 为空
|
||||
var wires []SWire
|
||||
if utils.IsInStringArray(region.Provider, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_UCLOUD}) {
|
||||
if utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) {
|
||||
wires, err = WireManager.getWiresByVpcAndZone(vpc, nil)
|
||||
} else {
|
||||
wires, err = WireManager.getWiresByVpcAndZone(vpc, zone)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInternalServerError("query wire for zone %s and vpc %s: %v", zoneStr, vpcStr, err)
|
||||
return nil, httperrors.NewInternalServerError("query wire for zone %s and vpc %s: %v", input.Zone, input.Vpc, err)
|
||||
}
|
||||
if len(wires) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("wire not found for zone %s and vpc %s", zoneStr, vpcStr)
|
||||
return nil, httperrors.NewNotFoundError("wire not found for zone %s and vpc %s", input.Zone, input.Vpc)
|
||||
} else if len(wires) > 1 {
|
||||
return nil, httperrors.NewConflictError("found %d wires for zone %s and vpc %s", len(wires), zoneStr, vpcStr)
|
||||
return nil, httperrors.NewConflictError("found %d wires for zone %s and vpc %s", len(wires), input.Zone, input.Vpc)
|
||||
} else {
|
||||
data.Add(jsonutils.NewString(wires[0].Id), "wire_id")
|
||||
input.WireId = wires[0].Id
|
||||
}
|
||||
} else {
|
||||
return nil, httperrors.NewInputParameterError("No either wire or vpc provided")
|
||||
@@ -1283,13 +1303,12 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
}
|
||||
|
||||
wireId, _ := data.GetString("wire_id")
|
||||
if len(wireId) == 0 {
|
||||
if len(input.WireId) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("wire_id")
|
||||
}
|
||||
wire := WireManager.FetchWireById(wireId)
|
||||
wire := WireManager.FetchWireById(input.WireId)
|
||||
if wire == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("wire %s not found", wireId)
|
||||
return nil, httperrors.NewResourceNotFoundError("wire %s not found", input.WireId)
|
||||
}
|
||||
vpc := wire.getVpc()
|
||||
if vpc == nil {
|
||||
@@ -1316,15 +1335,13 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
return nil, httperrors.NewInputParameterError("Network not in range of VPC cidrblock %s", vpc.CidrBlock)
|
||||
}
|
||||
|
||||
serverTypeStr, _ := data.GetString("server_type")
|
||||
if len(serverTypeStr) == 0 {
|
||||
serverTypeStr = api.NETWORK_TYPE_GUEST
|
||||
} else if !utils.IsInStringArray(serverTypeStr, ALL_NETWORK_TYPES) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid server_type: %s", serverTypeStr)
|
||||
if len(input.ServerType) == 0 {
|
||||
input.ServerType = api.NETWORK_TYPE_GUEST
|
||||
} else if !utils.IsInStringArray(input.ServerType, ALL_NETWORK_TYPES) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid server_type: %s", input.ServerType)
|
||||
}
|
||||
data.Add(jsonutils.NewString(serverTypeStr), "server_type")
|
||||
|
||||
return manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
|
||||
return manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.JSON(input))
|
||||
}
|
||||
|
||||
func (self *SNetwork) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
@@ -1613,10 +1630,10 @@ func (manager *SNetworkManager) CustomizeFilterList(ctx context.Context, q *sqlc
|
||||
return filters, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, input *api.NetworkListInput) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = managedResourceFilterByAccount(q, query, "wire_id", func() *sqlchemy.SQuery {
|
||||
q, err = managedResourceFilterByAccountV2(q, &input.CloudaccountListInput, "wire_id", func() *sqlchemy.SQuery {
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
|
||||
@@ -1628,7 +1645,7 @@ func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q = managedResourceFilterByCloudType(q, query, "wire_id", func() *sqlchemy.SQuery {
|
||||
q = managedResourceFilterByCloudTypeV2(q, &input.CloudTypeListInput, "wire_id", func() *sqlchemy.SQuery {
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
subq := wires.Query(wires.Field("id"))
|
||||
@@ -1636,21 +1653,20 @@ func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.
|
||||
return subq
|
||||
})
|
||||
|
||||
q, err = manager.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
q, err = manager.SSharableVirtualResourceBaseManager.ListItemFilterV2(ctx, q, userCred, &input.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zones := jsonutils.GetQueryStringArray(query, "zone")
|
||||
if len(zones) > 0 {
|
||||
if len(input.Zones) > 0 {
|
||||
zq := ZoneManager.Query().SubQuery()
|
||||
regions := CloudregionManager.Query().SubQuery()
|
||||
zoneQ := zq.Query(zq.Field("id"), regions.Field("id"), regions.Field("provider")).
|
||||
Join(regions, sqlchemy.Equals(zq.Field("cloudregion_id"), regions.Field("id"))).
|
||||
Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.In(zq.Field("id"), zones),
|
||||
sqlchemy.In(zq.Field("name"), zones),
|
||||
sqlchemy.In(zq.Field("id"), input.Zones),
|
||||
sqlchemy.In(zq.Field("name"), input.Zones),
|
||||
),
|
||||
)
|
||||
rows, err := zoneQ.Rows()
|
||||
@@ -1690,22 +1706,20 @@ func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.
|
||||
q = q.In("wire_id", sq.SubQuery())
|
||||
}
|
||||
|
||||
vpcStr, _ := query.GetString("vpc")
|
||||
if len(vpcStr) > 0 {
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred, vpcStr)
|
||||
if len(input.Vpc) > 0 {
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred, input.Vpc)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("VPC %s not found", vpcStr)
|
||||
return nil, httperrors.NewNotFoundError("VPC %s not found", input.Vpc)
|
||||
}
|
||||
sq := WireManager.Query("id").Equals("vpc_id", vpcObj.GetId())
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), sq.SubQuery()))
|
||||
}
|
||||
|
||||
regionStr := jsonutils.GetAnyString(query, []string{"region_id", "region", "cloudregion_id", "cloudregion"})
|
||||
if len(regionStr) > 0 {
|
||||
region, err := CloudregionManager.FetchByIdOrName(userCred, regionStr)
|
||||
if len(input.Cloudregion) > 0 {
|
||||
region, err := CloudregionManager.FetchByIdOrName(userCred, input.Cloudregion)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError("cloud region %s not found", regionStr)
|
||||
return nil, httperrors.NewResourceNotFoundError("cloud region %s not found", input.Cloudregion)
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
@@ -1719,7 +1733,7 @@ func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), sq.SubQuery()))
|
||||
}
|
||||
|
||||
if jsonutils.QueryBoolean(query, "usable", false) {
|
||||
if input.Usable {
|
||||
wires := WireManager.Query().SubQuery()
|
||||
zones := ZoneManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
@@ -1749,25 +1763,23 @@ func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.
|
||||
q = q.In("wire_id", sq.SubQuery()).Equals("status", api.NETWORK_STATUS_AVAILABLE)
|
||||
}
|
||||
|
||||
hostStr, _ := query.GetString("host")
|
||||
if len(hostStr) > 0 {
|
||||
hostObj, err := HostManager.FetchByIdOrName(userCred, hostStr)
|
||||
if len(input.Host) > 0 {
|
||||
hostObj, err := HostManager.FetchByIdOrName(userCred, input.Host)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewResourceNotFoundError2(HostManager.Keyword(), hostStr)
|
||||
return nil, httperrors.NewResourceNotFoundError2(HostManager.Keyword(), input.Host)
|
||||
}
|
||||
sq := HostwireManager.Query("wire_id").Equals("host_id", hostObj.GetId())
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), sq.SubQuery()))
|
||||
}
|
||||
|
||||
cityStr, _ := query.GetString("city")
|
||||
if len(cityStr) > 0 {
|
||||
if len(input.City) > 0 {
|
||||
regions := CloudregionManager.Query().SubQuery()
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
sq := wires.Query(wires.Field("id")).
|
||||
Join(vpcs, sqlchemy.Equals(wires.Field("vpc_id"), vpcs.Field("id"))).
|
||||
Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id"))).
|
||||
Filter(sqlchemy.Equals(regions.Field("city"), cityStr))
|
||||
Filter(sqlchemy.Equals(regions.Field("city"), input.City))
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), sq.SubQuery()))
|
||||
}
|
||||
|
||||
@@ -1846,7 +1858,9 @@ func (self *SNetwork) AllowPerformPurge(ctx context.Context, userCred mcclient.T
|
||||
return db.IsAdminAllowPerform(userCred, self, "purge")
|
||||
}
|
||||
|
||||
func (self *SNetwork) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
// 清除IP子网数据
|
||||
// 要求IP子网内没有被分配IP,若清除接入云,要求接入云账号处于禁用状态
|
||||
func (self *SNetwork) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkPurgeInput) (jsonutils.JSONObject, error) {
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1893,14 +1907,15 @@ func (manager *SNetworkManager) handleNetworkIdChange(ctx context.Context, args
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) PerformMerge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
target, err := data.GetString("target")
|
||||
if err != nil {
|
||||
// 合并IP子网
|
||||
// 将两个相连的IP子网合并成一个IP子网
|
||||
func (self *SNetwork) PerformMerge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkMergeInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.Target) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("target")
|
||||
}
|
||||
iNet, err := NetworkManager.FetchByIdOrName(userCred, target)
|
||||
iNet, err := NetworkManager.FetchByIdOrName(userCred, input.Target)
|
||||
if err == sql.ErrNoRows {
|
||||
err = httperrors.NewNotFoundError("Network %s not found", target)
|
||||
err = httperrors.NewNotFoundError("Network %s not found", input.Target)
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_MERGE, err.Error(), userCred, false)
|
||||
return nil, err
|
||||
} else if err != nil {
|
||||
@@ -1915,7 +1930,7 @@ func (self *SNetwork) PerformMerge(ctx context.Context, userCred mcclient.TokenC
|
||||
return nil, err
|
||||
}
|
||||
if self.WireId != net.WireId || self.GuestGateway != net.GuestGateway {
|
||||
err = httperrors.NewInputParameterError("Invalid Target Network: %s", target)
|
||||
err = httperrors.NewInputParameterError("Invalid Target Network: %s", input.Target)
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_MERGE, err.Error(), userCred, false)
|
||||
return nil, err
|
||||
}
|
||||
@@ -1972,50 +1987,53 @@ func (self *SNetwork) PerformMerge(ctx context.Context, userCred mcclient.TokenC
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) PerformSplit(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
splitIp, err := data.GetString("split_ip")
|
||||
if err != nil {
|
||||
// 分割IP子网
|
||||
// 将一个IP子网分割成两个子网,仅本地IDC支持此操作
|
||||
func (self *SNetwork) PerformSplit(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkSplitInput) (jsonutils.JSONObject, error) {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return nil, httperrors.NewNotSupportedError("only on premise support this operation")
|
||||
}
|
||||
|
||||
if len(input.SplitIp) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("split_ip")
|
||||
}
|
||||
name, _ := data.GetString("name")
|
||||
|
||||
if !regutils.MatchIPAddr(splitIp) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid IP %s", splitIp)
|
||||
if !regutils.MatchIPAddr(input.SplitIp) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid IP %s", input.SplitIp)
|
||||
}
|
||||
if splitIp == self.GuestIpStart {
|
||||
return nil, httperrors.NewInputParameterError("Split IP %s is the start ip", splitIp)
|
||||
if input.SplitIp == self.GuestIpStart {
|
||||
return nil, httperrors.NewInputParameterError("Split IP %s is the start ip", input.SplitIp)
|
||||
}
|
||||
|
||||
iSplitIp, err := netutils.NewIPV4Addr(splitIp)
|
||||
iSplitIp, err := netutils.NewIPV4Addr(input.SplitIp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !self.IsAddressInRange(iSplitIp) {
|
||||
return nil, httperrors.NewInputParameterError("Split IP %s out of range", splitIp)
|
||||
return nil, httperrors.NewInputParameterError("Split IP %s out of range", input.SplitIp)
|
||||
}
|
||||
|
||||
lockman.LockClass(ctx, NetworkManager, db.GetLockClassKey(NetworkManager, userCred))
|
||||
defer lockman.ReleaseClass(ctx, NetworkManager, db.GetLockClassKey(NetworkManager, userCred))
|
||||
|
||||
if len(name) > 0 {
|
||||
if err := db.NewNameValidator(NetworkManager, userCred, name, ""); err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Duplicate name %s", name)
|
||||
if len(input.Name) > 0 {
|
||||
if err := db.NewNameValidator(NetworkManager, userCred, input.Name, ""); err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Duplicate name %s", input.Name)
|
||||
}
|
||||
} else {
|
||||
newName, err := db.GenerateName(NetworkManager, userCred, fmt.Sprintf("%s#", self.Name))
|
||||
input.Name, err = db.GenerateName(NetworkManager, userCred, fmt.Sprintf("%s#", self.Name))
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInternalServerError("GenerateName fail %s", err)
|
||||
}
|
||||
name = newName
|
||||
}
|
||||
|
||||
network := &SNetwork{}
|
||||
network.Name = name
|
||||
network.IfnameHint, err = NetworkManager.newIfnameHint(name)
|
||||
network.Name = input.Name
|
||||
network.IfnameHint, err = NetworkManager.newIfnameHint(input.Name)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError("Generate ifname hint failed %s", err)
|
||||
}
|
||||
network.GuestIpStart = splitIp
|
||||
network.GuestIpStart = input.SplitIp
|
||||
network.GuestIpEnd = self.GuestIpEnd
|
||||
network.GuestIpMask = self.GuestIpMask
|
||||
network.GuestGateway = self.GuestGateway
|
||||
@@ -2053,7 +2071,7 @@ func (self *SNetwork) PerformSplit(ctx context.Context, userCred mcclient.TokenC
|
||||
return nil, err
|
||||
}
|
||||
|
||||
note := map[string]string{"split_ip": splitIp, "end_ip": network.GuestIpEnd}
|
||||
note := map[string]string{"split_ip": input.SplitIp, "end_ip": network.GuestIpEnd}
|
||||
db.OpsLog.LogEvent(self, db.ACT_SPLIT, note, userCred)
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_SPLIT, note, userCred, true)
|
||||
db.OpsLog.LogEvent(network, db.ACT_CREATE, map[string]string{"network": self.Id}, userCred)
|
||||
@@ -2064,37 +2082,34 @@ func (manager *SNetworkManager) AllowPerformTryCreateNetwork(ctx context.Context
|
||||
return db.IsAdminAllowClassPerform(userCred, manager, "try-create-network")
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) PerformTryCreateNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ip, err := data.GetString("ip")
|
||||
if err != nil {
|
||||
func (manager *SNetworkManager) PerformTryCreateNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkTryCreateNetworkInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.Ip) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("ip")
|
||||
}
|
||||
ipV4, err := netutils.NewIPV4Addr(ip)
|
||||
ipV4, err := netutils.NewIPV4Addr(input.Ip)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("ip")
|
||||
}
|
||||
mask, err := data.Int("mask")
|
||||
if err != nil {
|
||||
if input.Mask == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("mask")
|
||||
}
|
||||
serverType, err := data.GetString("server_type")
|
||||
if err != nil {
|
||||
if len(input.ServerType) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("server_type")
|
||||
}
|
||||
if serverType != api.NETWORK_TYPE_BAREMETAL {
|
||||
if input.ServerType != api.NETWORK_TYPE_BAREMETAL {
|
||||
return nil, httperrors.NewBadRequestError("Only support server type %s", api.NETWORK_TYPE_BAREMETAL)
|
||||
}
|
||||
if !jsonutils.QueryBoolean(data, "is_on_premise", false) {
|
||||
if !input.IsOnPremise {
|
||||
return nil, httperrors.NewBadRequestError("Only support on premise network")
|
||||
}
|
||||
|
||||
var (
|
||||
ipV4NetAddr = ipV4.NetAddr(int8(mask))
|
||||
ipV4NetAddr = ipV4.NetAddr(int8(input.Mask))
|
||||
nm *SNetwork
|
||||
matched bool
|
||||
)
|
||||
|
||||
q := NetworkManager.Query().Equals("server_type", serverType).Equals("guest_ip_mask", mask)
|
||||
q := NetworkManager.Query().Equals("server_type", input.ServerType).Equals("guest_ip_mask", input.Mask)
|
||||
q = managedResourceFilterByCloudType(q, query, "wire_id", func() *sqlchemy.SQuery {
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
@@ -2141,14 +2156,14 @@ func (manager *SNetworkManager) PerformTryCreateNetwork(ctx context.Context, use
|
||||
log.Infof("Find same subnet network %s %s/%d", nm.Name, nm.GuestGateway, nm.GuestIpMask)
|
||||
newNetwork := new(SNetwork)
|
||||
newNetwork.SetModelManager(NetworkManager, newNetwork)
|
||||
newNetwork.GuestIpStart = ip
|
||||
newNetwork.GuestIpEnd = ip
|
||||
newNetwork.GuestIpStart = input.Ip
|
||||
newNetwork.GuestIpEnd = input.Ip
|
||||
newNetwork.GuestGateway = nm.GuestGateway
|
||||
newNetwork.GuestIpMask = int8(mask)
|
||||
newNetwork.GuestIpMask = int8(input.Mask)
|
||||
newNetwork.GuestDns = nm.GuestDns
|
||||
newNetwork.GuestDhcp = nm.GuestDhcp
|
||||
newNetwork.WireId = nm.WireId
|
||||
newNetwork.ServerType = serverType
|
||||
newNetwork.ServerType = input.ServerType
|
||||
newNetwork.IsPublic = nm.IsPublic
|
||||
newNetwork.ProjectId = userCred.GetProjectId()
|
||||
newNetwork.DomainId = userCred.GetProjectDomainId()
|
||||
@@ -2162,11 +2177,11 @@ func (manager *SNetworkManager) PerformTryCreateNetwork(ctx context.Context, use
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = newNetwork.CustomizeCreate(ctx, userCred, userCred, query, data)
|
||||
err = newNetwork.CustomizeCreate(ctx, userCred, userCred, query, input.JSON(input))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newNetwork.PostCreate(ctx, userCred, userCred, query, data)
|
||||
newNetwork.PostCreate(ctx, userCred, userCred, query, input.JSON(input))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -2419,7 +2434,9 @@ func (net *SNetwork) AllowPerformSync(ctx context.Context, userCred mcclient.Tok
|
||||
return net.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, net, "sync")
|
||||
}
|
||||
|
||||
func (net *SNetwork) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
// 同步接入云IP子网状态
|
||||
// 本地IDC不支持此操作
|
||||
func (net *SNetwork) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkSyncInput) (jsonutils.JSONObject, error) {
|
||||
vpc := net.GetVpc()
|
||||
if vpc != nil && vpc.IsManaged() {
|
||||
err := net.StartNetworkSyncstatusTask(ctx, userCred, "")
|
||||
@@ -2444,17 +2461,17 @@ func (net *SNetwork) AllowPerformStatus(ctx context.Context, userCred mcclient.T
|
||||
return net.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, net, "status")
|
||||
}
|
||||
|
||||
func (net *SNetwork) PerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
status, _ := data.GetString("status")
|
||||
if len(status) == 0 {
|
||||
// 更改IP子网状态
|
||||
func (net *SNetwork) PerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.NetworkStatusInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.Status) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("status")
|
||||
}
|
||||
vpc := net.GetVpc()
|
||||
if vpc != nil && vpc.IsManaged() {
|
||||
return nil, httperrors.NewUnsupportOperationError("managed network cannot change status")
|
||||
}
|
||||
if !utils.IsInStringArray(status, []string{api.NETWORK_STATUS_AVAILABLE, api.NETWORK_STATUS_UNAVAILABLE}) {
|
||||
return nil, httperrors.NewInputParameterError("invalid status %s", status)
|
||||
if !utils.IsInStringArray(input.Status, []string{api.NETWORK_STATUS_AVAILABLE, api.NETWORK_STATUS_UNAVAILABLE}) {
|
||||
return nil, httperrors.NewInputParameterError("invalid status %s", input.Status)
|
||||
}
|
||||
return net.SSharableVirtualResourceBase.PerformStatus(ctx, userCred, query, data)
|
||||
return net.SSharableVirtualResourceBase.PerformStatus(ctx, userCred, query, input.JSON(input))
|
||||
}
|
||||
|
||||
@@ -344,6 +344,13 @@ func (self *SSchedtag) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
return desc
|
||||
}
|
||||
|
||||
func (self *SSchedtag) GetShortDescV2(ctx context.Context) *api.SchedtagShortDescDetails {
|
||||
desc := &api.SchedtagShortDescDetails{}
|
||||
desc.StandaloneResourceShortDescDetail = self.SStandaloneResourceBase.GetShortDescV2(ctx)
|
||||
desc.Default = self.DefaultStrategy
|
||||
return desc
|
||||
}
|
||||
|
||||
func GetResourceJointSchedtags(obj IModelWithSchedtag) ([]ISchedtagJointModel, error) {
|
||||
jointMan := obj.GetSchedtagJointManager()
|
||||
q := jointMan.Query().Equals(jointMan.GetMasterIdKey(jointMan), obj.GetId())
|
||||
@@ -470,6 +477,18 @@ func GetSchedtagsDetailsToResource(obj IModelWithSchedtag, ctx context.Context,
|
||||
return extra
|
||||
}
|
||||
|
||||
func GetSchedtagsDetailsToResourceV2(obj IModelWithSchedtag, ctx context.Context) []api.SchedtagShortDescDetails {
|
||||
info := []api.SchedtagShortDescDetails{}
|
||||
schedtags := GetSchedtags(obj.GetSchedtagJointManager(), obj.GetId())
|
||||
if schedtags != nil && len(schedtags) > 0 {
|
||||
for i := 0; i < len(schedtags); i += 1 {
|
||||
desc := schedtags[i].GetShortDescV2(ctx)
|
||||
info = append(info, *desc)
|
||||
}
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func (s *SSchedtag) AllowPerformSetScope(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -226,6 +226,12 @@ func (self *SVpc) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict
|
||||
return extra
|
||||
}
|
||||
|
||||
func (self *SVpc) getCloudProviderInfoV2() api.CloudproviderDetails {
|
||||
region, _ := self.GetRegion()
|
||||
provider := self.GetCloudprovider()
|
||||
return MakeCloudProviderInfoV2(region, nil, provider)
|
||||
}
|
||||
|
||||
func (self *SVpc) getCloudProviderInfo() SCloudProviderInfo {
|
||||
region, _ := self.GetRegion()
|
||||
provider := self.GetCloudprovider()
|
||||
|
||||
Reference in New Issue
Block a user