diff --git a/cmd/climc/shell/compute/external_projects.go b/cmd/climc/shell/compute/external_projects.go index 4e75ca327a..6a766009a9 100644 --- a/cmd/climc/shell/compute/external_projects.go +++ b/cmd/climc/shell/compute/external_projects.go @@ -15,57 +15,16 @@ package compute import ( - "yunion.io/x/jsonutils" - - "yunion.io/x/onecloud/pkg/mcclient" - modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute" + "yunion.io/x/onecloud/cmd/climc/shell" + "yunion.io/x/onecloud/pkg/mcclient/modules/compute" "yunion.io/x/onecloud/pkg/mcclient/options" + opts "yunion.io/x/onecloud/pkg/mcclient/options/compute" ) func init() { - type ExternalProjectListOptions struct { - options.BaseListOptions - } - R(&ExternalProjectListOptions{}, "external-project-list", "List public cloud projects", func(s *mcclient.ClientSession, opts *ExternalProjectListOptions) error { - params, err := options.ListStructToParams(opts) - if err != nil { - return err - } - - result, err := modules.ExternalProjects.List(s, params) - if err != nil { - return err - } - printList(result, modules.ExternalProjects.GetColumns(s)) - return nil - }) - - type ExternalProjectShowOptions struct { - ID string `help:"ID"` - } - R(&ExternalProjectShowOptions{}, "external-project-show", "Show details of project mapping", func(s *mcclient.ClientSession, args *ExternalProjectShowOptions) error { - info, err := modules.ExternalProjects.Get(s, args.ID, nil) - if err != nil { - return err - } - printObject(info) - return nil - }) - - type ExternalProjectUpdateOptions struct { - ID string `help:"ExternalProject ID or Name"` - PROJECT string `help:"Local project ID or Name"` - } - - R(&ExternalProjectUpdateOptions{}, "external-project-change-project", "Change external project point to local project", func(s *mcclient.ClientSession, args *ExternalProjectUpdateOptions) error { - params := jsonutils.NewDict() - params.Add(jsonutils.NewString(args.PROJECT), "project") - result, err := modules.ExternalProjects.PerformAction(s, args.ID, "change-project", params) - if err != nil { - return err - } - printObject(result) - return nil - }) - + cmd := shell.NewResourceCmd(&compute.ExternalProjects).WithKeyword("external-project") + cmd.List(&opts.ExternalProjectListOptions{}) + cmd.Create(&opts.ExternalProjectCreateOptions{}) + cmd.Show(&options.BaseIdOptions{}) + cmd.Perform("change-project", &opts.ExterProjectChagneProjectOptions{}) } diff --git a/pkg/apis/compute/externalproject.go b/pkg/apis/compute/externalproject.go index bfb79b0620..ee1a430ede 100644 --- a/pkg/apis/compute/externalproject.go +++ b/pkg/apis/compute/externalproject.go @@ -24,6 +24,12 @@ const ( EXTERNAL_PROJECT_STATUS_UNKNOWN = "unknown" // 未知 ) +var ( + MANGER_EXTERNAL_PROJECT_PROVIDERS = []string{ + CLOUD_PROVIDER_AZURE, + } +) + type ExternalProjectDetails struct { apis.VirtualResourceDetails ManagedResourceInfo @@ -34,3 +40,13 @@ type ExternalProjectDetails struct { type ExternalProjectChangeProjectInput struct { apis.ProjectizedResourceInput } + +type ExternalProjectCreateInput struct { + apis.VirtualResourceCreateInput + + CloudaccountId string `json:"cloudaccount_id"` + ManagerId string `json:"manager_id"` + + // swagger:ignore + ExternalId string `json:"external_id"` +} diff --git a/pkg/compute/models/external_projects.go b/pkg/compute/models/external_projects.go index 058d5cef30..3d8c69cb2a 100644 --- a/pkg/compute/models/external_projects.go +++ b/pkg/compute/models/external_projects.go @@ -31,6 +31,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/consts" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" + "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/httperrors" @@ -69,7 +70,56 @@ type SExternalProject struct { ExternalDomainId string `width:"36" charset:"ascii" nullable:"true" list:"user"` // 归属云账号ID - CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user"` + CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"` +} + +func (manager *SExternalProjectManager) ValidateCreateData( + ctx context.Context, + userCred mcclient.TokenCredential, + ownerId mcclient.IIdentityProvider, + query jsonutils.JSONObject, + input api.ExternalProjectCreateInput, +) (api.ExternalProjectCreateInput, error) { + var err error + if len(input.CloudaccountId) == 0 { + return input, httperrors.NewMissingParameterError("cloudaccount_id") + } + _account, err := validators.ValidateModel(userCred, CloudaccountManager, &input.CloudaccountId) + if err != nil { + return input, err + } + account := _account.(*SCloudaccount) + driver, err := account.GetProvider(ctx) + if err != nil { + return input, err + } + if utils.IsInStringArray(account.Provider, api.MANGER_EXTERNAL_PROJECT_PROVIDERS) { + if len(input.ManagerId) == 0 { + return input, httperrors.NewMissingParameterError("manager_id") + } + _provider, err := validators.ValidateModel(userCred, CloudproviderManager, &input.ManagerId) + if err != nil { + return input, err + } + provider := _provider.(*SCloudprovider) + driver, err = provider.GetProvider(ctx) + if err != nil { + return input, err + } + } + + input.VirtualResourceCreateInput, err = manager.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.VirtualResourceCreateInput) + if err != nil { + return input, errors.Wrap(err, "SVirtualResourceBaseManager.ValidateCreateData") + } + + iProj, err := driver.CreateIProject(input.Name) + if err != nil { + return input, errors.Wrapf(err, "CreateIProject") + } + input.ExternalId = iProj.GetGlobalId() + input.Status = api.EXTERNAL_PROJECT_STATUS_AVAILABLE + return input, nil } func (manager *SExternalProjectManager) FetchCustomizeColumns( diff --git a/pkg/mcclient/options/compute/external_projects.go b/pkg/mcclient/options/compute/external_projects.go new file mode 100644 index 0000000000..0e52f43657 --- /dev/null +++ b/pkg/mcclient/options/compute/external_projects.go @@ -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 + +import ( + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/mcclient/options" +) + +type ExternalProjectListOptions struct { + options.BaseListOptions +} + +func (opts *ExternalProjectListOptions) Params() (jsonutils.JSONObject, error) { + return options.ListStructToParams(opts) +} + +type ExternalProjectIdOption struct { + ID string `help:"external project Id"` +} + +func (opts *ExternalProjectIdOption) GetId() string { + return opts.ID +} + +func (opts *ExternalProjectIdOption) Params() (jsonutils.JSONObject, error) { + return nil, nil +} + +type ExterProjectChagneProjectOptions struct { + ExternalProjectIdOption + PROJECT string +} + +func (opts *ExterProjectChagneProjectOptions) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(map[string]string{"project": opts.PROJECT}), nil +} + +type ExternalProjectCreateOptions struct { + NAME string + CLOUDACCOUNT_ID string + ManagerId string +} + +func (opts *ExternalProjectCreateOptions) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(opts), nil +}