support generate

This commit is contained in:
Zexi Li
2019-11-19 19:14:49 +08:00
parent ec97345c31
commit cfa6fc4cfe
29 changed files with 2327 additions and 108 deletions

1
.gitignore vendored
View File

@@ -33,3 +33,4 @@ _output
GPATH
GRTAGS
GTAGS
pkg/generated

View File

@@ -232,3 +232,21 @@ endef
help: export helpText:=$(helpText)
help:
@echo "$$helpText"
gen-model-api-check:
which swagger-gen || (GO111MODULE=off go get -u github.com/yunionio/code-generator/cmd/model-api-gen)
gen-model-api:
./scripts/codegen.sh model_api
gen-swagger-check:
which swagger || (GO111MODULE=off go get -u github.com/go-swagger/go-swagger/cmd/swagger)
which swagger-gen || (GO111MODULE=off go get -u github.com/yunionio/code-generator/cmd/swagger-gen)
which swagger-serve || (GO111MODULE=off go get -u github.com/yunionio/code-generator/cmd/swagger-serve)
gen-swagger: gen-swagger-check
./scripts/codegen.sh swagger_spec
./scripts/codegen.sh swagger_yaml
swagger-serve: gen-swagger
./scripts/codegen.sh swagger_serve

View File

@@ -0,0 +1,15 @@
// 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 cloudprovider // import "yunion.io/x/onecloud/pkg/apis/cloudprovider"

View File

@@ -0,0 +1,23 @@
// 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.
// Code generated by model-api-gen. DO NOT EDIT.
package cloudprovider
// SGeographicInfo is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SGeographicInfo.
type SGeographicInfo struct {
Latitude float32 `json:"latitude"`
Longitude float32 `json:"longitude"`
City string `json:"city"`
CountryCode string `json:"country_code"`
}

View File

@@ -14,6 +14,10 @@
package compute
import (
"yunion.io/x/onecloud/pkg/apis"
)
const (
BUCKET_OPS_STATS_CHANGE = "stats_change"
@@ -30,3 +34,17 @@ const (
BUCKET_UPLOAD_OBJECT_ACL_HEADER = "X-Yunion-Bucket-Upload-Acl"
BUCKET_UPLOAD_OBJECT_STORAGECLASS_HEADER = "X-Yunion-Bucket-Upload-Storageclass"
)
type BucketCreateInput struct {
apis.Meta
Name string `json:"name"`
Cloudregion string `json:"cloudregion"`
Manager string `json:"manager"`
StorageClass string `json:"storage_class"`
Description string `json:"description"`
}
type BucketDetail struct {
SBucket
}

View File

@@ -7,7 +7,10 @@ import (
type ServerRebuildRootInput struct {
apis.Meta
Image string `json:"image"`
// 镜像名称
Image string `json:"image"`
// 镜像 id
// required: true
ImageId string `json:"image_id"`
Keypair string `json:"keypair"`
KeypairId string `json:"keypair_id"`

File diff suppressed because it is too large Load Diff

View File

@@ -15,35 +15,35 @@
package identity
type SIdentityObject struct {
Id string
Name string
Id string `json:"id"`
Name string `json:"name"`
}
type SDomainObject struct {
SIdentityObject
Domain SIdentityObject
Domain SIdentityObject `json:"domain"`
}
type SFetchDomainObject struct {
SIdentityObject
Domain string
DomainId string
Domain string `json:"domain"`
DomainId string `json:"domain_id"`
}
type SRoleAssignment struct {
Scope struct {
Domain SIdentityObject
Project SDomainObject
}
User SDomainObject
Group SDomainObject
Role SDomainObject
Domain SIdentityObject `json:"domain"`
Project SDomainObject `json:"project"`
} `json:"scope"`
User SDomainObject `json:"user"`
Group SDomainObject `json:"group"`
Role SDomainObject `json:"role"`
Policies struct {
Project []string
Domain []string
System []string
}
Project []string `json:"project"`
Domain []string `json:"domain"`
System []string `json:"system"`
} `json:"policies"`
}
// rbacutils.IRbacIdentity interfaces

View File

@@ -0,0 +1,184 @@
// 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.
// Code generated by model-api-gen. DO NOT EDIT.
package identity
import (
time "time"
jsonutils "yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/apis"
)
// SAssignment is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SAssignment.
type SAssignment struct {
apis.SResourceBase
Type string `json:"type"`
ActorId string `json:"actor_id"`
TargetId string `json:"target_id"`
RoleId string `json:"role_id"`
Inherited *bool `json:"inherited,omitempty"`
}
// SConfigOption is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SConfigOption.
type SConfigOption struct {
apis.SResourceBase
ResType string `json:"res_type"`
ResId string `json:"res_id"`
Group string `json:"group"`
Option string `json:"option"`
Value jsonutils.JSONObject `json:"value"`
}
// SCredential is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SCredential.
type SCredential struct {
apis.SStandaloneResourceBase
UserId string `json:"user_id"`
ProjectId string `json:"project_id"`
Type string `json:"type"`
KeyHash string `json:"key_hash"`
Extra *jsonutils.JSONDict `json:"extra"`
EncryptedBlob string `json:"encrypted_blob"`
Enabled *bool `json:"enabled,omitempty"`
}
// SDomain is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SDomain.
type SDomain struct {
apis.SStandaloneResourceBase
Extra *jsonutils.JSONDict `json:"extra"`
Enabled *bool `json:"enabled,omitempty"`
IsDomain *bool `json:"is_domain,omitempty"`
DomainId string `json:"domain_id"`
ParentId string `json:"parent_id"`
}
// SEnabledIdentityBaseResource is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SEnabledIdentityBaseResource.
type SEnabledIdentityBaseResource struct {
SIdentityBaseResource
Enabled *bool `json:"enabled,omitempty"`
}
// SEndpoint is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SEndpoint.
type SEndpoint struct {
apis.SStandaloneResourceBase
LegacyEndpointId string `json:"legacy_endpoint_id"`
Interface string `json:"interface"`
ServiceId string `json:"service_id"`
Url string `json:"url"`
Extra *jsonutils.JSONDict `json:"extra"`
Enabled *bool `json:"enabled,omitempty"`
RegionId string `json:"region_id"`
}
// SFederatedUser is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SFederatedUser.
type SFederatedUser struct {
apis.SResourceBase
Id int `json:"id"`
UserId string `json:"user_id"`
IdpId string `json:"idp_id"`
ProtocolId string `json:"protocol_id"`
UniqueId string `json:"unique_id"`
DisplayName string `json:"display_name"`
}
// SIdentityBaseResource is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SIdentityBaseResource.
type SIdentityBaseResource struct {
apis.SStandaloneResourceBase
apis.SDomainizedResourceBase
Extra *jsonutils.JSONDict `json:"extra"`
}
// SIdentityProvider is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SIdentityProvider.
type SIdentityProvider struct {
apis.SEnabledStatusStandaloneResourceBase
Driver string `json:"driver"`
Template string `json:"template"`
TargetDomainId string `json:"target_domain_id"`
AutoCreateProject *bool `json:"auto_create_project,omitempty"`
ErrorCount int `json:"error_count"`
SyncStatus string `json:"sync_status"`
LastSync time.Time `json:"last_sync"`
LastSyncEndAt time.Time `json:"last_sync_end_at"`
SyncIntervalSeconds int `json:"sync_interval_seconds"`
}
// SIdmapping is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SIdmapping.
type SIdmapping struct {
apis.SResourceBase
PublicId string `json:"public_id"`
IdpId string `json:"idp_id"`
IdpEntityId string `json:"idp_entity_id"`
EntityType string `json:"entity_type"`
}
// SLocalUser is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SLocalUser.
type SLocalUser struct {
apis.SResourceBase
Id int `json:"id"`
UserId string `json:"user_id"`
DomainId string `json:"domain_id"`
Name string `json:"name"`
FailedAuthCount int `json:"failed_auth_count"`
FailedAuthAt time.Time `json:"failed_auth_at"`
}
// SPassword is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SPassword.
type SPassword struct {
apis.SResourceBase
Id int `json:"id"`
LocalUserId int `json:"local_user_id"`
Password string `json:"password"`
ExpiresAt time.Time `json:"expires_at"`
SelfService bool `json:"self_service"`
PasswordHash string `json:"password_hash"`
CreatedAtInt int64 `json:"created_at_int"`
ExpiresAtInt int64 `json:"expires_at_int"`
}
// SPolicy is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SPolicy.
type SPolicy struct {
SEnabledIdentityBaseResource
apis.SSharableBaseResource
Type string `json:"type"`
Blob jsonutils.JSONObject `json:"blob"`
}
// SRegion is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SRegion.
type SRegion struct {
apis.SStandaloneResourceBase
ParentRegionId string `json:"parent_region_id"`
Extra *jsonutils.JSONDict `json:"extra"`
}
// SRole is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SRole.
type SRole struct {
SIdentityBaseResource
apis.SSharableBaseResource
}
// SService is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SService.
type SService struct {
apis.SStandaloneResourceBase
Type string `json:"type"`
Enabled *bool `json:"enabled,omitempty"`
Extra *jsonutils.JSONDict `json:"extra"`
}
// SUsergroupMembership is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SUsergroupMembership.
type SUsergroupMembership struct {
apis.SResourceBase
UserId string `json:"user_id"`
GroupId string `json:"group_id"`
}

View File

@@ -0,0 +1,57 @@
// 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.
// Code generated by model-api-gen. DO NOT EDIT.
package image
import (
"yunion.io/x/onecloud/pkg/apis"
)
// SGuestImage is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SGuestImage.
type SGuestImage struct {
apis.SSharableVirtualResourceBase
Protected *bool `json:"omitempty,protected"`
}
// SGuestImageJoint is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SGuestImageJoint.
type SGuestImageJoint struct {
apis.SJointResourceBase
GuestImageId string `json:"guest_image_id"`
ImageId string `json:"image_id"`
}
// SImage is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImage.
type SImage struct {
apis.SSharableVirtualResourceBase
Size int64 `json:"size"`
Location string `json:"location"`
DiskFormat string `json:"disk_format"`
Checksum string `json:"checksum"`
FastHash string `json:"fast_hash"`
Owner string `json:"owner"`
MinDiskMB int32 `json:"min_disk_mb"`
MinRamMB int32 `json:"min_ram_mb"`
Protected *bool `json:"omitempty,protected"`
IsStandard *bool `json:"is_standard,omitempty"`
IsGuestImage *bool `json:"is_guest_image,omitempty"`
IsData *bool `json:"is_data,omitempty"`
OssChecksum string `json:"oss_checksum"`
}
// SImagePeripheral is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImagePeripheral.
type SImagePeripheral struct {
apis.SResourceBase
Id int `json:"id"`
ImageId string `json:"image_id"`
}

View File

@@ -0,0 +1,128 @@
// 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.
// Code generated by model-api-gen. DO NOT EDIT.
package apis
import (
time "time"
)
// SAdminSharableVirtualResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SAdminSharableVirtualResourceBase.
type SAdminSharableVirtualResourceBase struct {
SSharableVirtualResourceBase
Records string `json:"records"`
}
// SDomainizedResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SDomainizedResourceBase.
type SDomainizedResourceBase struct {
DomainId string `json:"domain_id"`
}
// SEnabledStatusStandaloneResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SEnabledStatusStandaloneResourceBase.
type SEnabledStatusStandaloneResourceBase struct {
SStatusStandaloneResourceBase
Enabled bool `json:"enabled"`
}
// SExternalizedResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SExternalizedResourceBase.
type SExternalizedResourceBase struct {
ExternalId string `json:"external_id"`
}
// SJointResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SJointResourceBase.
type SJointResourceBase struct {
SResourceBase
RowId int64 `json:"row_id"`
}
// SKeystoneCacheObject is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SKeystoneCacheObject.
type SKeystoneCacheObject struct {
SStandaloneResourceBase
DomainId string `json:"domain_id"`
Domain string `json:"domain"`
LastCheck time.Time `json:"last_check"`
}
// SProjectizedResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SProjectizedResourceBase.
type SProjectizedResourceBase struct {
SDomainizedResourceBase
ProjectId string `json:"project_id"`
}
// SResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SResourceBase.
type SResourceBase struct {
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
UpdateVersion int `json:"update_version"`
DeletedAt time.Time `json:"deleted_at"`
Deleted bool `json:"deleted"`
}
// SScopedResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SScopedResourceBase.
type SScopedResourceBase struct {
DomainId string `json:"domain_id"`
ProjectId string `json:"project_id"`
}
// SSharableBaseResource is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SSharableBaseResource.
type SSharableBaseResource struct {
IsPublic bool `json:"is_public"`
}
// SSharableVirtualResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SSharableVirtualResourceBase.
type SSharableVirtualResourceBase struct {
SVirtualResourceBase
IsPublic bool `json:"is_public"`
PublicScope string `json:"public_scope"`
}
// SSharedResource is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SSharedResource.
type SSharedResource struct {
SResourceBase
Id int64 `json:"id"`
ResourceType string `json:"resource_type"`
ResourceId string `json:"resource_id"`
OwnerProjectId string `json:"owner_project_id"`
TargetProjectId string `json:"target_project_id"`
}
// SStandaloneResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SStandaloneResourceBase.
type SStandaloneResourceBase struct {
SResourceBase
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
IsEmulated bool `json:"is_emulated"`
}
// SStatusStandaloneResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SStatusStandaloneResourceBase.
type SStatusStandaloneResourceBase struct {
SStandaloneResourceBase
Status string `json:"status"`
}
// SVirtualJointResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SVirtualJointResourceBase.
type SVirtualJointResourceBase struct {
SJointResourceBase
}
// SVirtualResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SVirtualResourceBase.
type SVirtualResourceBase struct {
SStatusStandaloneResourceBase
SProjectizedResourceBase
ProjectSrc string `json:"project_src"`
IsSystem bool `json:"is_system"`
PendingDeletedAt time.Time `json:"pending_deleted_at"`
PendingDeleted bool `json:"pending_deleted"`
}

View File

@@ -0,0 +1,202 @@
// 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 db
import (
"context"
"fmt"
"reflect"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type Caller struct {
modelVal reflect.Value
funcName string
inputs []interface{}
funcVal reflect.Value
}
func NewCaller(model interface{}, fName string) *Caller {
return &Caller{
modelVal: reflect.ValueOf(model),
funcName: fName,
}
}
func (c *Caller) Inputs(inputs ...interface{}) *Caller {
c.inputs = inputs
return c
}
func (c *Caller) Call() ([]reflect.Value, error) {
return callObject(c.modelVal, c.funcName, c.inputs...)
}
func call(obj interface{}, fName string, inputs ...interface{}) ([]reflect.Value, error) {
return call(reflect.ValueOf(obj), fName, inputs...)
}
func callObject(modelVal reflect.Value, fName string, inputs ...interface{}) ([]reflect.Value, error) {
funcVal := modelVal.MethodByName(fName)
return callFunc(funcVal, inputs...)
}
func callFunc(funcVal reflect.Value, inputs ...interface{}) ([]reflect.Value, error) {
fName := funcVal.String()
if !funcVal.IsValid() || funcVal.IsNil() {
return nil, httperrors.NewActionNotFoundError(fmt.Sprintf("%s method not found", fName))
}
funcType := funcVal.Type()
paramLen := funcType.NumIn()
if paramLen != len(inputs) {
return nil, httperrors.NewInternalServerError("%s method params length not match, expected %d, input %d", fName, paramLen, len(inputs))
}
params := make([]*param, paramLen)
for i := range inputs {
params[i] = newParam(funcType.In(i), inputs[i])
}
args := convertParams(params)
return funcVal.Call(args), nil
}
func convertParams(params []*param) []reflect.Value {
ret := make([]reflect.Value, 0)
for _, p := range params {
ret = append(ret, p.convert())
}
return ret
}
type param struct {
pType reflect.Type
input reflect.Value
}
func newParam(pType reflect.Type, input interface{}) *param {
return &param{
pType: pType,
input: reflect.ValueOf(input),
}
}
func isJSONObject(val reflect.Value) (jsonutils.JSONObject, bool) {
obj, ok := val.Interface().(jsonutils.JSONObject)
if !ok {
return nil, false
}
return obj, true
}
func (p *param) convert() reflect.Value {
obj, ok := isJSONObject(p.input)
if !ok {
return p.input
}
// generate object by type
val := reflect.New(p.pType)
obj.Unmarshal(val.Interface())
return val.Elem()
}
func ValueToJSONObject(out reflect.Value) jsonutils.JSONObject {
if obj, ok := isJSONObject(out); ok {
return obj
}
return jsonutils.Marshal(out.Interface())
}
func ValueToError(out reflect.Value) error {
errVal := out.Interface()
if !gotypes.IsNil(errVal) {
return errVal.(error)
}
return nil
}
func ValidateCreateData(manager IModelManager, ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
ret, err := call(manager, "ValidateCreateData", userCred, ownerId, query, data)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(ret) != 2 {
return nil, httperrors.NewInternalServerError("Invald ValidateCreateData return value")
}
resVal := ret[0]
if err := ValueToError(ret[1]); err != nil {
return nil, err
}
return ValueToJSONObject(resVal).(*jsonutils.JSONDict), nil
}
func ListItemFilter(manager IModelManager, ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
ret, err := call(manager, "ListItemFilter", ctx, q, userCred, query)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(ret) != 2 {
return nil, httperrors.NewInternalServerError("Invald ListItemFilter return value")
}
if err := ValueToError(ret[1]); err != nil {
return nil, err
}
return ret[0].Interface().(*sqlchemy.SQuery), nil
}
func GetExtraDetails(model IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
ret, err := call(model, "GetExtraDetails", ctx, userCred, query)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(ret) != 2 {
return nil, httperrors.NewInternalServerError("Invald GetExtraDetails return value")
}
if err := ValueToError(ret[1]); err != nil {
return nil, err
}
return ValueToJSONObject(ret[0]).(*jsonutils.JSONDict), nil
}
func ValidateUpdateData(model IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
ret, err := call(model, "ValidateUpdateData", userCred, query, data)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(ret) != 2 {
return nil, httperrors.NewInternalServerError("Invald ValidateUpdateData return value")
}
resVal := ret[0]
if err := ValueToError(ret[1]); err != nil {
return nil, err
}
return ValueToJSONObject(resVal).(*jsonutils.JSONDict), nil
}
func CustomizeDelete(model IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
ret, err := call(model, "CustomizeDelete", userCred, query, data)
if err != nil {
return httperrors.NewGeneralError(err)
}
if len(ret) != 1 {
return httperrors.NewInternalServerError("Invald CustomizeDelete return value")
}
return ValueToError(ret[0])
}

View File

@@ -0,0 +1,119 @@
// 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 db
import (
"context"
"reflect"
"testing"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
)
func Test_valueToJSONObject(t *testing.T) {
tests := []struct {
name string
args interface{}
want jsonutils.JSONObject
}{
{
name: "json2json",
args: jsonutils.NewDict(),
want: jsonutils.NewDict(),
},
{
name: "struct2json",
args: &api.ServerRebuildRootInput{Image: "image"},
want: jsonutils.Marshal(api.ServerRebuildRootInput{Image: "image"}),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ValueToJSONObject(reflect.ValueOf(tt.args)); !reflect.DeepEqual(got, tt.want) {
t.Errorf("toJSONObject() = %v, want %v", got, tt.want)
}
})
}
}
type fakeModel struct{}
func (m *fakeModel) PerformAction(ctx context.Context, input *api.ServerRebuildRootInput) *api.SGuest {
log.Infof("input: %#v", input)
out := new(api.SGuest)
out.Id = input.ImageId
return out
}
func Test_call(t *testing.T) {
type args struct {
modelVal reflect.Value
fName string
inputs []interface{}
}
fModel := new(fakeModel)
c1Out := new(api.SGuest)
c1Out.Id = "id"
tests := []struct {
name string
args args
want []reflect.Value
wantErr bool
}{
{
name: "input struct",
args: args{
modelVal: reflect.ValueOf(fModel),
fName: "PerformAction",
inputs: []interface{}{context.TODO(), &api.ServerRebuildRootInput{ImageId: "id"}},
},
want: []reflect.Value{reflect.ValueOf(c1Out)},
wantErr: false,
},
{
name: "input json object",
args: args{
modelVal: reflect.ValueOf(fModel),
fName: "PerformAction",
inputs: []interface{}{context.TODO(), jsonutils.Marshal(api.ServerRebuildRootInput{ImageId: "id"})},
},
want: []reflect.Value{reflect.ValueOf(c1Out)},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := callObject(tt.args.modelVal, tt.args.fName, tt.args.inputs...)
if (err != nil) != tt.wantErr {
t.Errorf("call() error = %v, wantErr %v", err, tt.wantErr)
return
}
log.Infof("out1 %s", jsonutils.Marshal(got[0].Interface()))
for i := range got {
gi := got[i].Interface()
wt := tt.want[i].Interface()
if !reflect.DeepEqual(gi, wt) {
t.Errorf("call() = %v, want %v", got, tt.want)
}
}
})
}
}

View File

@@ -255,7 +255,7 @@ func listItemQueryFilters(manager IModelManager,
q = manager.FilterBySystemAttributes(q, userCred, query, queryScope)
q = manager.FilterByHiddenSystemAttributes(q, userCred, query, queryScope)
q, err = manager.ListItemFilter(ctx, q, userCred, query)
q, err = ListItemFilter(manager, ctx, q, userCred, query)
if err != nil {
return nil, err
}
@@ -709,7 +709,7 @@ func getModelItemDetails(manager IModelManager, item IModel, ctx context.Context
}
func getItemDetails(manager IModelManager, item IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
extraDict, err := item.GetExtraDetails(ctx, userCred, query)
extraDict, err := GetExtraDetails(item, ctx, userCred, query)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
@@ -822,11 +822,7 @@ func (dispatcher *DBModelDispatcher) GetSpecific(ctx context.Context, idStr stri
return nil, err
}
params := []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(userCred),
reflect.ValueOf(query),
}
params := []interface{}{ctx, userCred, query}
specCamel := utils.Kebab2Camel(spec, "-")
modelValue := reflect.ValueOf(model)
@@ -844,7 +840,10 @@ func (dispatcher *DBModelDispatcher) GetSpecific(ctx context.Context, idStr stri
return nil, httperrors.NewSpecNotFoundError("%s %s %s not found", dispatcher.Keyword(), idStr, spec)
}
outs := funcValue.Call(params)
outs, err := callFunc(funcValue, params...)
if err != nil {
return nil, err
}
if len(outs) != 1 {
return nil, httperrors.NewInternalServerError("Invald %s return value", funcName)
}
@@ -859,20 +858,23 @@ func (dispatcher *DBModelDispatcher) GetSpecific(ctx context.Context, idStr stri
return nil, httperrors.NewSpecNotFoundError("%s %s %s not found", dispatcher.Keyword(), idStr, spec)
}
outs := funcValue.Call(params)
outs, err := callFunc(funcValue, params...)
if err != nil {
return nil, err
}
if len(outs) != 2 {
return nil, httperrors.NewInternalServerError("Invald %s return value", funcName)
}
resVal := outs[0].Interface()
resVal := outs[0]
errVal := outs[1].Interface()
if !gotypes.IsNil(errVal) {
return nil, errVal.(error)
} else {
if gotypes.IsNil(resVal) {
if gotypes.IsNil(resVal.Interface()) {
return nil, nil
} else {
return resVal.(jsonutils.JSONObject), nil
return ValueToJSONObject(resVal), nil
}
}
}
@@ -1013,7 +1015,7 @@ func _doCreateItem(
if batchCreate {
dataDict, err = manager.BatchCreateValidateCreateData(ctx, userCred, ownerId, query, dataDict)
} else {
dataDict, err = manager.ValidateCreateData(ctx, userCred, ownerId, query, dataDict)
dataDict, err = ValidateCreateData(manager, ctx, userCred, ownerId, query, dataDict)
}
if err != nil {
@@ -1265,7 +1267,7 @@ func managerPerformCheckCreateData(
return nil, httperrors.NewForbiddenError("not allow to perform %s", action)
}
return manager.ValidateCreateData(ctx, userCred, ownerId, query, bodyDict)
return ValidateCreateData(manager, ctx, userCred, ownerId, query, bodyDict)
}
func (dispatcher *DBModelDispatcher) PerformClassAction(ctx context.Context, action string, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
@@ -1358,23 +1360,12 @@ func reflectDispatcherInternal(
}
}
var params []reflect.Value
var params []interface{}
if isGeneral {
params = []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(userCred),
reflect.ValueOf(spec),
reflect.ValueOf(query),
reflect.ValueOf(data),
}
params = []interface{}{ctx, userCred, spec, query, data}
} else {
params = []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(userCred),
reflect.ValueOf(query),
reflect.ValueOf(data),
}
params = []interface{}{ctx, userCred, query, data}
}
if consts.IsRbacEnabled() {
@@ -1402,7 +1393,10 @@ func reflectDispatcherInternal(
return nil, httperrors.NewActionNotFoundError(msg)
}
outs := allowFuncValue.Call(params)
outs, err := callFunc(allowFuncValue, params...)
if err != nil {
return nil, err
}
if len(outs) != 1 {
return nil, httperrors.NewInternalServerError("Invald %s return value", allowFuncName)
}
@@ -1412,19 +1406,22 @@ func reflectDispatcherInternal(
}
}
outs := funcValue.Call(params)
outs, err := callFunc(funcValue, params...)
if err != nil {
return nil, err
}
if len(outs) != 2 {
return nil, httperrors.NewInternalServerError("Invald %s return value", funcName)
}
resVal := outs[0].Interface()
resVal := outs[0]
errVal := outs[1].Interface()
if !gotypes.IsNil(errVal) {
return nil, errVal.(error)
} else {
if gotypes.IsNil(resVal) {
if gotypes.IsNil(resVal.Interface()) {
return nil, nil
} else {
return resVal.(jsonutils.JSONObject), nil
return ValueToJSONObject(resVal), nil
}
}
}
@@ -1452,7 +1449,7 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre
}
}
dataDict, err = item.ValidateUpdateData(ctx, userCred, query, dataDict)
dataDict, err = ValidateUpdateData(item, ctx, userCred, query, dataDict)
if err != nil {
errMsg := fmt.Sprintf("validate update data error: %s", err)
log.Errorf(errMsg)
@@ -1563,7 +1560,7 @@ func deleteItem(manager IModelManager, model IModel, ctx context.Context, userCr
return nil, err
}
err = model.CustomizeDelete(ctx, userCred, query, data)
err = CustomizeDelete(model, ctx, userCred, query, data)
if err != nil {
log.Errorf("customize delete error: %s", err)
return nil, httperrors.NewNotAcceptableError(err.Error())

View File

@@ -52,7 +52,8 @@ type IModelManager interface {
// list hooks
AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool
ValidateListConditions(ctx context.Context, userCred mcclient.TokenCredential, query *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error)
// ListItemFilter dynamic called by dispatcher
// ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error)
CustomizeFilterList(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*CustomizeListFilters, error)
ExtraSearchConditions(ctx context.Context, q *sqlchemy.SQuery, like string) []sqlchemy.ICondition
GetExportExtraKeys(ctx context.Context, query jsonutils.JSONObject, rowMap map[string]string) *jsonutils.JSONDict
@@ -80,7 +81,8 @@ type IModelManager interface {
// create hooks
AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool
BatchCreateValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
// ValidateCreateData dynamic called by dispatcher
// ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
OnCreateComplete(ctx context.Context, items []IModel, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject)
BatchPreValidate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject, data *jsonutils.JSONDict, count int) (func(), error)
@@ -139,7 +141,8 @@ type IModel interface {
// get hooks
AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool
GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error)
// GetExtraDetails dynamic call by model dispatcher
// GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error)
GetExtraDetailsHeaders(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) map[string]string
// create hooks
@@ -154,7 +157,7 @@ type IModel interface {
ValidateUpdateCondition(ctx context.Context) error
AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool
ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
// ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
PreUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject)
PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject)
@@ -163,7 +166,7 @@ type IModel interface {
// delete hooks
AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool
ValidateDeleteCondition(ctx context.Context) error
CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error
// CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error
PreDelete(ctx context.Context, userCred mcclient.TokenCredential)
MarkDelete() error
Delete(ctx context.Context, userCred mcclient.TokenCredential) error

View File

@@ -29,6 +29,10 @@ import (
var globalTables map[string]IModelManager
func GlobalModelManagerTables() map[string]IModelManager {
return globalTables
}
func RegisterModelManager(modelMan IModelManager) {
if globalTables == nil {
globalTables = make(map[string]IModelManager)

View File

@@ -14,6 +14,7 @@
package cloudprovider
// +onecloud:model-api-gen
type SGeographicInfo struct {
Latitude float32 `list:"user" update:"admin" create:"admin_optional"`
Longitude float32 `list:"user" update:"admin" create:"admin_optional"`

View File

@@ -391,8 +391,9 @@ func (manager *SBucketManager) ValidateCreateData(
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
data *jsonutils.JSONDict,
input *api.BucketCreateInput,
) (*jsonutils.JSONDict, error) {
data := input.JSON(input)
cloudRegionV := validators.NewModelIdOrNameValidator("cloudregion", CloudregionManager.Keyword(), ownerId)
managerV := validators.NewModelIdOrNameValidator("manager", CloudproviderManager.Keyword(), ownerId)
for _, v := range []validators.IValidator{
@@ -492,12 +493,15 @@ func (bucket *SBucket) GetCustomizeColumns(ctx context.Context, userCred mcclien
return bucket.getMoreDetails(extra)
}
func (bucket *SBucket) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
func (bucket *SBucket) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*api.BucketDetail, error) {
extra, err := bucket.SVirtualResourceBase.GetExtraDetails(ctx, userCred, query)
if err != nil {
return nil, err
}
return bucket.getMoreDetails(extra), nil
ret := bucket.getMoreDetails(extra)
out := new(api.BucketDetail)
err = ret.Unmarshal(out)
return out, err
}
func joinPath(ep, path string) string {

View File

@@ -1303,13 +1303,8 @@ func (self *SGuest) AllowPerformRebuildRoot(ctx context.Context, userCred mcclie
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "rebuild-root")
}
func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
input := api.ServerRebuildRootInput{}
err := data.Unmarshal(&input)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid input: %s", err)
}
// 重装系统(更换系统镜像)
func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ServerRebuildRootInput) (*api.SGuest, error) {
imageId := input.GetImageName()
if len(imageId) > 0 {

View File

@@ -1269,6 +1269,7 @@ func (manager *SGuestManager) BatchCreateValidateCreateData(ctx context.Context,
return input.JSON(input), nil
}
// 创建虚拟机实例
func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
input, err := manager.validateCreateData(ctx, userCred, ownerId, query, data)
if err != nil {

View File

@@ -28,7 +28,7 @@ const (
API_VERSION = "v1"
)
func initHandlers(app *appsrv.Application) {
func InitHandlers(app *appsrv.Application) {
db.InitAllManagers()
// add version handler with API_VERSION prefix

View File

@@ -89,7 +89,7 @@ func StartService() {
}
app := app_common.InitApp(baseOpts, true)
initHandlers(app)
InitHandlers(app)
db.EnsureAppInitSyncDB(app, dbOpts, models.InitDB)

View File

@@ -28,7 +28,7 @@ const (
API_VERSION = "v3"
)
func initHandlers(app *appsrv.Application) {
func InitHandlers(app *appsrv.Application) {
db.InitAllManagers()
// add version handler with API_VERSION prefix

View File

@@ -70,7 +70,7 @@ func StartService() {
*/
app := app_common.InitApp(&opts.BaseOptions, true)
initHandlers(app)
InitHandlers(app)
db.EnsureAppInitSyncDB(app, &opts.DBOptions, models.InitDB)

View File

@@ -248,6 +248,13 @@ func authUserByAccessKeyV3(ctx context.Context, input mcclient.SAuthenticationIn
return usrExt, credential.ProjectId, aksk, nil
}
// +onecloud:swagger-gen-route-method=POST
// +onecloud:swagger-gen-route-path=/v3/auth/tokens
// +onecloud:swagger-gen-route-tag=authentication
// +onecloud:swagger-gen-param-body-index=1
// +onecloud:swagger-gen-resp-index=0
// keystone keystone v3认证API
func AuthenticateV3(ctx context.Context, input mcclient.SAuthenticationInputV3) (*mcclient.TokenCredentialV3, error) {
var akskInfo api.SAccessKeySecretInfo
var user *api.SUserExtended
@@ -346,6 +353,13 @@ func AuthenticateV3(ctx context.Context, input mcclient.SAuthenticationInputV3)
return tokenV3, nil
}
// +onecloud:swagger-gen-route-method=POST
// +onecloud:swagger-gen-route-path=/v2.0/tokens
// +onecloud:swagger-gen-route-tag=authentication
// +onecloud:swagger-gen-param-body-index=1
// +onecloud:swagger-gen-resp-index=0
// keystone v2 认证接口,通过用户名/密码或者 token 认证
func AuthenticateV2(ctx context.Context, input mcclient.SAuthenticationInputV2) (*mcclient.TokenCredentialV2, error) {
var user *api.SUserExtended
var err error

View File

@@ -42,14 +42,22 @@ type SAuthenticationInputV2 struct {
}
type SAuthenticationIdentity struct {
Methods []string `json:"methods,omitempty"`
// 认证方式列表
Methods []string `json:"methods,omitempty"`
// 密码认证信息
Password struct {
User struct {
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
// 用户ID
Id string `json:"id,omitempty"`
// 用户名称
Name string `json:"name,omitempty"`
// 密码
Password string `json:"password,omitempty"`
Domain struct {
Id string `json:"id,omitempty"`
// 域的信息
Domain struct {
// 域ID
Id string `json:"id,omitempty"`
// 域名称
Name string `json:"name,omitempty"`
}
} `json:"user,omitempty"`

View File

@@ -27,61 +27,61 @@ import (
)
type KeystoneEndpointV2 struct {
Id string
InternalURL string
PublicURL string
AdminURL string
Region string
Id string `json:"id"`
InternalURL string `json:"internal_url"`
PublicURL string `json:"public_url"`
AdminURL string `json:"admin_url"`
Region string `json:"region"`
}
type KeystoneServiceV2 struct {
Name string
Type string
Endpoints []KeystoneEndpointV2
Name string `json:"name"`
Type string `json:"type"`
Endpoints []KeystoneEndpointV2 `json:"endpoints"`
}
type KeystoneRoleV2 struct {
Name string
Name string `json:"name"`
}
type KeystoneUserV2 struct {
Id string
Name string
Username string
Roles []KeystoneRoleV2
Id string `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Roles []KeystoneRoleV2 `json:"roles"`
}
type KeystoneTenantV2 struct {
Id string
Name string
Enabled bool
Description string
Id string `json:"id"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
Description string `json:"description"`
Domain struct {
Id string
Name string
}
Id string `json:"id"`
Name string `json:"name"`
} `json:"domain"`
}
type KeystoneTokenV2 struct {
Id string
Expires time.Time
Tenant KeystoneTenantV2
Id string `json:"id"`
Expires time.Time `json:"expires"`
Tenant KeystoneTenantV2 `json:"tenant"`
}
type KeystoneMetadataV2 struct {
IsAdmin int
Roles []string
IsAdmin int `json:"is_admin"`
Roles []string `json:"roles"`
}
type KeystoneServiceCatalogV2 []KeystoneServiceV2
type TokenCredentialV2 struct {
Token KeystoneTokenV2
ServiceCatalog KeystoneServiceCatalogV2
User KeystoneUserV2
Tenants []KeystoneTenantV2
Metadata KeystoneMetadataV2
Context SAuthContext
Token KeystoneTokenV2 `json:"token"`
ServiceCatalog KeystoneServiceCatalogV2 `json:"service_catalog"`
User KeystoneUserV2 `json:"user"`
Tenants []KeystoneTenantV2 `json:"tenants"`
Metadata KeystoneMetadataV2 `json:"metadata"`
Context SAuthContext `json:"context"`
}
func (token *TokenCredentialV2) GetTokenString() string {

View File

@@ -450,7 +450,7 @@ func DeleteItem(model db.IModel, ctx context.Context, userCred mcclient.TokenCre
log.Errorf("validate delete condition error: %s", err)
return err
}
err = model.CustomizeDelete(ctx, userCred, query, data)
err = db.CustomizeDelete(model, ctx, userCred, query, data)
if err != nil {
log.Errorf("customize delete error: %s", err)
return httperrors.NewNotAcceptableError(err.Error())
@@ -482,7 +482,7 @@ func UpdateItem(manager db.IModelManager, item db.IModel, ctx context.Context, u
return httperrors.NewInternalServerError("Invalid data JSONObject")
}
dataDict, err = item.ValidateUpdateData(ctx, userCred, query, dataDict)
dataDict, err = db.ValidateUpdateData(item, ctx, userCred, query, dataDict)
if err != nil {
errMsg := fmt.Sprintf("validate update data error: %s", err)
log.Errorf(errMsg)

104
scripts/codegen.sh Executable file
View File

@@ -0,0 +1,104 @@
#!/bin/bash
set -o errexit
set -o pipefail
ONECLOUD="yunion.io/x/onecloud"
PKG_ONECLOUD="$ONECLOUD/pkg"
PKG_APIS="$PKG_ONECLOUD/apis"
PKG_GENERATED="$PKG_ONECLOUD/generated"
PKG_SWAGGER="$PKG_GENERATED/swagger"
MODEL_API_PKG_MAP=(
"$PKG_ONECLOUD/cloudcommon/db:$PKG_APIS"
"$PKG_ONECLOUD/cloudprovider:$PKG_APIS/cloudprovider"
"$PKG_ONECLOUD/compute/models:$PKG_APIS/compute"
"$PKG_ONECLOUD/image/models:$PKG_APIS/image"
"$PKG_ONECLOUD/keystone/models:$PKG_APIS/identity"
)
MODEL_SWAGGER_PKG_MAP=(
"$PKG_ONECLOUD/compute/models:$PKG_SWAGGER/compute"
"$PKG_ONECLOUD/image/models:$PKG_SWAGGER/image"
"$PKG_ONECLOUD/keystone/models:$PKG_SWAGGER/identity"
)
CURDIR="$(dirname $(dirname $0))"
DOCS_DIR="$CURDIR/docs"
OUTPUT_DIR="$CURDIR/_output"
OUTPUT_SWAGGER_DIR="$OUTPUT_DIR/swagger"
generate_model_api() {
for pkg_path in "${MODEL_API_PKG_MAP[@]}"; do
model_pkg="${pkg_path%%:*}"
api_pkg="${pkg_path##*:}"
model-api-gen \
--input-dirs $model_pkg \
--output-package $api_pkg
done
}
generate_swagger_spec() {
# for pkg_path in "${MODEL_SWAGGER_PKG_MAP[@]}"; do
# model_pkg="${pkg_path%%:*}"
# swaager_pkg="${pkg_path##*:}"
# swagger-gen \
# --input-dirs $model_pkg \
# --output-package $swaager_pkg
# done
swagger-gen \
-i "$PKG_ONECLOUD/compute/models" \
-p "$PKG_SWAGGER/compute"
swagger-gen \
-i "$PKG_ONECLOUD/image/models" \
-p "$PKG_SWAGGER/image"
swagger-gen \
-i "$PKG_ONECLOUD/keystone/tokens" \
-i "$PKG_ONECLOUD/keystone/models" \
-p "$PKG_SWAGGER/identity"
}
generate_swagger_yaml() {
mkdir -p "$OUTPUT_SWAGGER_DIR"
for pkg_path in "${MODEL_SWAGGER_PKG_MAP[@]}"; do
model_pkg="${pkg_path%%:*}"
swaager_pkg="${pkg_path##*:}"
work_dir=${swaager_pkg#"$ONECLOUD"}
GO111MODULE=off swagger generate spec \
--scan-models \
--work-dir="$CURDIR/$work_dir" \
-o "$OUTPUT_SWAGGER_DIR/swagger_$(basename $swaager_pkg).yaml"
done
}
generate_swagger_serve() {
input_files="$(find $OUTPUT_SWAGGER_DIR -name 'swagger_*.yaml' -type f | paste -sd,)"
swagger-serve generate -i "$input_files" -o "$OUTPUT_SWAGGER_DIR" --serve
}
show_help() {
cat <<EOF
usage: $(basename $0) <subcommand>
Subcommands:
model_api: genereate model struct code
swagger_spec: generate swagger spec code
swagger_serve: generate swagger web site
EOF
}
subcmd=$1
case $subcmd in
"" | "-h" | "--help")
show_help
;;
*)
shift
generate_${subcmd} $@
if [ $? = 127 ]; then
echo "Run --help for a list of known subcommands." >&2
exit 1
fi
;;
esac