openapi/invoker.go (146 lines of code) (raw):

// Copyright (c) 2009-present, Alibaba Cloud All rights reserved. // // 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 openapi import ( "fmt" "os" "strings" "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" "github.com/aliyun/aliyun-cli/v3/cli" "github.com/aliyun/aliyun-cli/v3/config" "github.com/aliyun/aliyun-cli/v3/meta" ) func GetClient(cp *config.Profile, ctx *cli.Context) (client *sdk.Client, err error) { credential, err := cp.GetCredential(ctx, nil) if err != nil { return } model, err := credential.GetCredential() if err != nil { return } var cred auth.Credential if model.SecurityToken != nil { cred = credentials.NewStsTokenCredential(*model.AccessKeyId, *model.AccessKeySecret, *model.SecurityToken) } else { cred = credentials.NewAccessKeyCredential(*model.AccessKeyId, *model.AccessKeySecret) } if cp.RegionId == "" { err = fmt.Errorf("default RegionId is empty! run `aliyun configure` first") return } conf := sdk.NewConfig() client, err = sdk.NewClientWithOptions(cp.RegionId, conf, cred) if err != nil { return } // get UserAgent from env conf.UserAgent = os.Getenv("ALIYUN_USER_AGENT") if cp.RetryCount > 0 { // when use --retry-count, enable auto retry conf.WithAutoRetry(true) conf.WithMaxRetryTime(cp.RetryCount) } if client != nil { if cp.ReadTimeout > 0 { client.SetReadTimeout(time.Duration(cp.ReadTimeout) * time.Second) } if cp.ConnectTimeout > 0 { client.SetConnectTimeout(time.Duration(cp.ConnectTimeout) * time.Second) } if config.SkipSecureVerify(ctx.Flags()).IsAssigned() { client.SetHTTPSInsecure(true) } } return client, err } // implementations: // - RpcInvoker, // - RpcForceInvoker // - RestfulInvoker type Invoker interface { getClient() *sdk.Client getRequest() *requests.CommonRequest Prepare(ctx *cli.Context) error Call() (*responses.CommonResponse, error) } // implementations // - Waiter // - Pager type InvokeHelper interface { CallWith(invoker Invoker) (string, error) } // basic invoker to init common object and headers type BasicInvoker struct { profile *config.Profile client *sdk.Client request *requests.CommonRequest product *meta.Product } func NewBasicInvoker(cp *config.Profile) *BasicInvoker { return &BasicInvoker{profile: cp} } func (a *BasicInvoker) getClient() *sdk.Client { return a.client } func (a *BasicInvoker) getRequest() *requests.CommonRequest { return a.request } func (a *BasicInvoker) Init(ctx *cli.Context, product *meta.Product) error { var err error a.product = product a.request = requests.NewCommonRequest() a.request.Product = product.Code a.request.RegionId = a.profile.RegionId if v, ok := config.RegionFlag(ctx.Flags()).GetValue(); ok { a.request.RegionId = v } else if v, ok := config.RegionIdFlag(ctx.Flags()).GetValue(); ok { a.request.RegionId = v } a.request.Version = product.Version if v, ok := VersionFlag(ctx.Flags()).GetValue(); ok { a.request.Version = v } if v, ok := EndpointFlag(ctx.Flags()).GetValue(); ok { a.request.Domain = v } for _, s := range HeaderFlag(ctx.Flags()).GetValues() { if k, v, ok := cli.SplitStringWithPrefix(s, "="); ok { a.request.Headers[k] = v if k == "Accept" { if strings.Contains(v, "xml") { a.request.AcceptFormat = "XML" } else if strings.Contains(v, "json") { a.request.AcceptFormat = "JSON" } } if k == "Content-Type" { a.request.SetContentType(v) } } else { return fmt.Errorf("invaild flag --header `%s` use `--header HeaderName=Value`", s) } } hint := "you can find it on https://help.aliyun.com" if product.Version != "" { hint = fmt.Sprintf("please use `aliyun help %s` get more information.", product.GetLowerCode()) } if a.request.Version == "" { return cli.NewErrorWithTip(fmt.Errorf("missing version for product %s", product.Code), "Use flag `--version <YYYY-MM-DD>` to assign version, "+hint) } if a.request.RegionId == "" { return cli.NewErrorWithTip(fmt.Errorf("missing region for product %s", product.Code), "Use flag --region <regionId> to assign region, "+hint) } a.client, err = GetClient(a.profile, ctx) if err != nil { return fmt.Errorf("init client failed %s", err) } if vendorEnv, ok := os.LookupEnv("ALIBABA_CLOUD_VENDOR"); ok { a.client.AppendUserAgent("vendor", vendorEnv) } a.client.AppendUserAgent("Aliyun-CLI", cli.GetVersion()) if a.request.Domain == "" { a.request.Domain, err = product.GetEndpoint(a.request.RegionId, a.client) if err != nil { return cli.NewErrorWithTip( fmt.Errorf("unknown endpoint for %s/%s! failed %s", product.GetLowerCode(), a.request.RegionId, err), "Use flag --endpoint xxx.aliyuncs.com to assign endpoint, "+hint) } } return nil }