diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/examples/cluster-autoscaler-secret.yaml b/cluster-autoscaler/cloudprovider/huaweicloud/examples/cluster-autoscaler-secret.yaml index bbc5705e8f01..e0f6f762c4ee 100644 --- a/cluster-autoscaler/cloudprovider/huaweicloud/examples/cluster-autoscaler-secret.yaml +++ b/cluster-autoscaler/cloudprovider/huaweicloud/examples/cluster-autoscaler-secret.yaml @@ -8,12 +8,8 @@ type: Opaque stringData: cloud-config: |- [Global] - identity-endpoint=https://{Identity Endpoint}/v3.0 ecs-endpoint=https://{ECS endpoint} as-endpoint=https://{AS endpoint} project-id={Project ID} access-key={Access Key} secret-key={Secret Key} - cloud=myhuaweicloud.com - region={Region} - domain-id={Domain ID} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/LICENSE b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/LICENSE deleted file mode 100644 index 9ffa80be0e7b..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/LICENSE +++ /dev/null @@ -1,208 +0,0 @@ -Copyright 2012-2013 Rackspace, Inc. - -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. - ------- - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - -Huawei has modified some source files which you can find the license update in -the files. - -Copyright 2020 Huawei Technologies Co., Ltd. - -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. diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/aksk_options.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/aksk_options.go deleted file mode 100644 index 4cdf41541c0c..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/aksk_options.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 aksk - -// AKSKOptions presents the required information for AK/SK auth -type AKSKOptions struct { - IdentityEndpoint string `json:"-" required:"true"` // HTTP endpoint for identity API. - ProjectID string // user project id - DomainID string `json:"-" required:"true"` // Huawei cloud account id - Region string // eg. "cn-north-1" for "Beijing1", "cn-north-4" for "Beijing4" - Domain string // Cloud name - Cloud string // Cloud name - AccessKey string // Access Key - SecretKey string // Secret key - SecurityToken string // If AK/SK is used, token won't be used. -} - -// GetIdentityEndpoint implements the method of AuthOptionsProvider -func (opts AKSKOptions) GetIdentityEndpoint() string { - return opts.IdentityEndpoint -} - -//GetProjectId implements the method of AuthOptionsProvider -func (opts AKSKOptions) GetProjectId() string { - return opts.ProjectID -} - -// GetDomainId implements the method of AuthOptionsProvider -func (opts AKSKOptions) GetDomainId() string { - return opts.DomainID -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/aksk_signer.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/aksk_signer.go deleted file mode 100644 index 8c83eda65572..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/aksk_signer.go +++ /dev/null @@ -1,476 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 aksk providers functions for sign http request before request cloud. -*/ -package aksk - -import ( - "bytes" - "crypto/hmac" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "fmt" - "io/ioutil" - "log" - "net/http" - "net/textproto" - "net/url" - "regexp" - "sort" - "strings" - "time" -) - -// caseInsencitiveStringArray represents string case insensitive sorting operations -type caseInsencitiveStringArray []string - -// noEscape specifies whether the character should be encoded or not -var noEscape [256]bool - -func init() { - // refer to https://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html - for i := 0; i < len(noEscape); i++ { - noEscape[i] = (i >= 'A' && i <= 'Z') || - (i >= 'a' && i <= 'z') || - (i >= '0' && i <= '9') || - i == '.' || - i == '-' || - i == '_' || - i == '~' //java-sdk-core 3.0.1 HttpUtils.urlEncode - } -} - -/* -SignOptions represents the options during signing http request, it is concurrency safely. -Sample code: - - client := &http.Client{ - Timeout: time.Duration(3 * time.Second), - } - req, err := http.NewRequest("POST", "https://30030113-3657-4fb6-a7ef-90764239b038.apigw.xxx.yyy.com/app1?name=value",bytes.NewBuffer([]byte("demo"))) - - signOptions := signer.SignOptions{ - AccessKey: "------------", - SecretKey: "------------", - } - - signer.Sign(req, signOptions) - resp, err := client.Do(req) -*/ -type SignOptions struct { - AccessKey string //Access Key - SecretKey string //Secret key - RegionName string // Region name - ServiceName string // Service Name - EnableCacheSignKey bool // Cache sign key for one day or not cache, cache is disabled by default - encodeUrl bool //internal use - SignAlgorithm string //The algorithm used for sign, the default value is "SDK-HMAC-SHA256" if you don't set its value - TimeOffsetInseconds int64 // TimeOffsetInseconds is used for adjust x-sdk-date if set its value -} - -// StringBuilder wraps bytes.Buffer to implement a high performance string builder. -type StringBuilder struct { - builder bytes.Buffer //string storage -} - -// reqSignParams represents the option values used for signing http request. -type reqSignParams struct { - SignOptions - RequestTime time.Time - Req *http.Request -} - -// signKeyCacheEntry represents the cache entry of sign key. -type signKeyCacheEntry struct { - Key []byte // sign key - NumberOfDaysSinceEpoch int64 // number of days since epoch -} - -// SignAlgorithmHMACSHA256 The default sign algorithm -const SignAlgorithmHMACSHA256 = "SDK-HMAC-SHA256" - -// ContentSha256HeaderKey The header key of content hash value -const ContentSha256HeaderKey = "x-sdk-content-sha256" - -// A regular for searching empty string -var spaceRegexp = regexp.MustCompile(`\s+`) - -// cache sign key -var cache = NewCache(300) - -// Sign manipulates the http.Request instance with some required authentication headers for SK/SK auth. -func Sign(req *http.Request, signOptions SignOptions) { - signOptions.AccessKey = strings.TrimSpace(signOptions.AccessKey) - signOptions.SecretKey = strings.TrimSpace(signOptions.SecretKey) - signOptions.encodeUrl = true - - signParams := reqSignParams{ - SignOptions: signOptions, - RequestTime: time.Now(), - Req: req, - } - - //t, _ := time.Parse(time.RFC3339, "2018-04-15T04:28:22+00:00") - //signParams.RequestTime = t - - if signParams.SignAlgorithm == "" { - signParams.SignAlgorithm = SignAlgorithmHMACSHA256 - } - - addRequiredHeaders(req, signParams.getFormattedSigningDateTime()) - contentSha256 := "" - - if v, ok := req.Header[textproto.CanonicalMIMEHeaderKey(ContentSha256HeaderKey)]; !ok { - contentSha256 = calculateContentHash(req) - } else { - contentSha256 = v[0] - } - - canonicalRequest := createCanonicalRequest(signParams, contentSha256) - - /*fmt.Println("canonicalRequest: " + canonicalRequest) - fmt.Println("*****")*/ - - strToSign := createStringToSign(canonicalRequest, signParams) - signKey := deriveSigningKey(signParams) - signature := computeSignature(strToSign, signKey, signParams.SignAlgorithm) - - req.Header.Set("Authorization", buildAuthorizationHeader(signParams, signature)) -} - -// deriveSigningKey returns a sign key from cache, or build it and insert it into cache -func deriveSigningKey(signParam reqSignParams) []byte { - if signParam.EnableCacheSignKey { - cacheKey := strings.Join([]string{signParam.SecretKey, - signParam.RegionName, - signParam.ServiceName, - }, "-") - - cacheData := cache.Get(cacheKey) - - if cacheData != "" { - var signKey signKeyCacheEntry - json.Unmarshal([]byte(cacheData), &signKey) - - if signKey.NumberOfDaysSinceEpoch == signParam.getDaysSinceEpon() { - return signKey.Key - } - } - - signKey := buildSignKey(signParam) - signKeyStr, _ := json.Marshal(signKeyCacheEntry{ - Key: signKey, - NumberOfDaysSinceEpoch: signParam.getDaysSinceEpon(), - }) - cache.Add(cacheKey, string(signKeyStr)) - return signKey - } - - return buildSignKey(signParam) -} - -func buildSignKey(signParam reqSignParams) []byte { - var kSecret StringBuilder - kSecret.Write("SDK").Write(signParam.SecretKey) - - kDate := computeSignature(signParam.getFormattedSigningDate(), kSecret.GetBytes(), signParam.SignAlgorithm) - kRegion := computeSignature(signParam.RegionName, kDate, signParam.SignAlgorithm) - kService := computeSignature(signParam.ServiceName, kRegion, signParam.SignAlgorithm) - return computeSignature("sdk_request", kService, signParam.SignAlgorithm) -} - -// HmacSha256 implements the Keyed-Hash Message Authentication Code computation. -func HmacSha256(data string, key []byte) []byte { - mac := hmac.New(sha256.New, key) - mac.Write([]byte(data)) - return mac.Sum(nil) -} - -// HashSha256 is a wrapper for sha256 implementation. -func HashSha256(msg []byte) []byte { - sh256 := sha256.New() - sh256.Write(msg) - - return sh256.Sum(nil) -} - -// buildAuthorizationHeader builds the authentication header value -func buildAuthorizationHeader(signParam reqSignParams, signature []byte) string { - var signingCredentials StringBuilder - signingCredentials.Write(signParam.AccessKey).Write("/").Write(signParam.getScope()) - - credential := "Credential=" + signingCredentials.ToString() - signerHeaders := "SignedHeaders=" + getSignedHeadersString(signParam.Req) - signatureHeader := "Signature=" + hex.EncodeToString(signature) - - return signParam.SignAlgorithm + " " + strings.Join([]string{ - credential, - signerHeaders, - signatureHeader, - }, ", ") -} - -// computeSignature computers the signature with the specified algorithm -// and it only supports SDK-HMAC-SHA256 in currently -func computeSignature(signData string, key []byte, algorithm string) []byte { - if algorithm == SignAlgorithmHMACSHA256 { - return HmacSha256(signData, key) - } - log.Fatalf("Unsupported algorithm %s, please use %s and try again", algorithm, SignAlgorithmHMACSHA256) - return nil -} - -// createStringToSign build the need to be signed string -func createStringToSign(canonicalRequest string, signParams reqSignParams) string { - return strings.Join([]string{signParams.SignAlgorithm, - signParams.getFormattedSigningDateTime(), - signParams.getScope(), - hex.EncodeToString(HashSha256([]byte(canonicalRequest))), - }, "\n") -} - -// getCanonicalizedResourcePath builds the valid url path for signing -func getCanonicalizedResourcePath(signParas reqSignParams) string { - urlStr := signParas.Req.URL.Path - if !strings.HasPrefix(urlStr, "/") { - urlStr = "/" + urlStr - } - - if !strings.HasSuffix(urlStr, "/") { - urlStr = urlStr + "/" - } - - if signParas.encodeUrl { - urlStr = urlEncode(urlStr, true) - } - - if urlStr == "" { - urlStr = "/" - } - - return urlStr -} - -// urlEncode encodes url path and url querystring according to the following rules: -// The alphanumeric characters "a" through "z", "A" through "Z" and "0" through "9" remain the same. -//The special characters ".", "-", "*", and "_" remain the same. -//The space character " " is converted into a plus sign "%20". -//All other characters are unsafe and are first converted into one or more bytes using some encoding scheme. -func urlEncode(url string, urlPath bool) string { - var buf bytes.Buffer - for i := 0; i < len(url); i++ { - c := url[i] - if noEscape[c] || (c == '/' && urlPath) { - buf.WriteByte(c) - } else { - fmt.Fprintf(&buf, "%%%02X", c) - } - } - - return buf.String() -} - -// encodeQueryString build and encode querystring to a string for signing -func encodeQueryString(queryValues url.Values) string { - var encodedVals = make(map[string]string, len(queryValues)) - var keys = make([]string, len(queryValues)) - - i := 0 - - for k := range queryValues { - keys[i] = urlEncode(k, false) - encodedVals[keys[i]] = k - i++ - } - - caseInsensitiveSort(keys) - - var queryStr StringBuilder - for i, k := range keys { - if i > 0 { - queryStr.Write("&") - } - - queryStr.Write(k).Write("=").Write(urlEncode(queryValues.Get(encodedVals[k]), false)) - } - - return queryStr.ToString() -} - -// getCanonicalizedQueryString return empty string if in POST method and content is nil, otherwise returns sorted,encoded querystring -func getCanonicalizedQueryString(signParas reqSignParams) string { - if usePayloadForQueryParameters(signParas.Req) { - return "" - } - return encodeQueryString(signParas.Req.URL.Query()) -} - -// createCanonicalRequest builds canonical string depends the official document for signing -func createCanonicalRequest(signParas reqSignParams, contentSha256 string) string { - return strings.Join([]string{signParas.Req.Method, - getCanonicalizedResourcePath(signParas), - getCanonicalizedQueryString(signParas), - getCanonicalizedHeaderString(signParas.Req), - getSignedHeadersString(signParas.Req), - contentSha256, - }, "\n") -} - -// calculateContentHash computes the content hash value -func calculateContentHash(req *http.Request) string { - encodeParas := "" - - //post and content is null use queryString as content -- according to document - if usePayloadForQueryParameters(req) { - encodeParas = req.URL.Query().Encode() - } else { - if req.Body == nil { - encodeParas = "" - } else { - readBody, _ := ioutil.ReadAll(req.Body) - req.Body = ioutil.NopCloser(bytes.NewBuffer(readBody)) - encodeParas = string(readBody) - } - } - - return hex.EncodeToString(HashSha256([]byte(encodeParas))) -} - -// usePayloadForQueryParameters specifies use querystring or not as content for compute content hash -func usePayloadForQueryParameters(req *http.Request) bool { - if strings.ToLower(req.Method) != "post" { - return false - } - - return req.Body == nil -} - -// getCanonicalizedHeaderString converts header map to a string for signing -func getCanonicalizedHeaderString(req *http.Request) string { - var headers StringBuilder - - keys := make([]string, 0) - for k := range req.Header { - keys = append(keys, strings.TrimSpace(k)) - } - - caseInsensitiveSort(keys) - - for _, k := range keys { - k = strings.ToLower(k) - newKey := spaceRegexp.ReplaceAllString(k, " ") - headers.Write(newKey) - headers.Write(":") - - val := req.Header.Get(k) - val = spaceRegexp.ReplaceAllString(val, " ") - headers.Write(val) - - headers.Write("\n") - } - - return headers.ToString() -} - -// getSignedHeadersString builds the string for AuthorizationHeader and signing -func getSignedHeadersString(req *http.Request) string { - var headers StringBuilder - - keys := make([]string, 0) - for k := range req.Header { - keys = append(keys, strings.TrimSpace(k)) - } - - caseInsensitiveSort(keys) - - for idx, k := range keys { - - if idx > 0 { - headers.Write(";") - } - - headers.Write(strings.ToLower(k)) - } - - return headers.ToString() -} - -// addRequiredHeaders adds the required heads to http.request instance -func addRequiredHeaders(req *http.Request, timeStr string) { - // golang handls port by default - req.Header.Add("Host", req.URL.Host) - req.Header.Add("X-Sdk-Date", timeStr) -} - -func (s caseInsencitiveStringArray) Len() int { - return len(s) -} -func (s caseInsencitiveStringArray) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s caseInsencitiveStringArray) Less(i, j int) bool { - return strings.ToLower(s[i]) < strings.ToLower(s[j]) -} - -func caseInsensitiveSort(strSlice []string) { - sort.Sort(caseInsencitiveStringArray(strSlice)) -} - -func (signParas *reqSignParams) getSigningDateTimeMilli() int64 { - return (signParas.RequestTime.UTC().Unix() - signParas.TimeOffsetInseconds) * 1000 -} - -func (signParas *reqSignParams) getSigningDateTime() time.Time { - return time.Unix(signParas.getSigningDateTimeMilli()/1000, 0) -} - -func (signParas *reqSignParams) getDaysSinceEpon() int64 { - return signParas.getSigningDateTimeMilli() / 1000 / 3600 / 24 -} - -func (signParas *reqSignParams) getFormattedSigningDate() string { - return signParas.getSigningDateTime().UTC().Format("20060102") -} -func (signParas *reqSignParams) getFormattedSigningDateTime() string { - return signParas.getSigningDateTime().UTC().Format("20060102T150405Z") -} - -func (signParas *reqSignParams) getScope() string { - return strings.Join([]string{signParas.getFormattedSigningDate(), - signParas.RegionName, - signParas.ServiceName, - "sdk_request", - }, "/") -} - -// Write ... -func (buff *StringBuilder) Write(s string) *StringBuilder { - buff.builder.WriteString(s) - return buff -} - -// ToString ... -func (buff *StringBuilder) ToString() string { - return buff.builder.String() -} - -// GetBytes ... -func (buff *StringBuilder) GetBytes() []byte { - return []byte(buff.ToString()) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/cache.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/cache.go deleted file mode 100644 index 75746a5c9863..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk/cache.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 aksk - -import "sync" - -// MemoryCache presents a thread safe memory cache -type MemoryCache struct { - sync.Mutex // handling r/w for cache - cacheHolder map[string]string // cache holder - cacheKeys []string // cache keys - MaxCount int // max cache entry count -} - -// NewCache inits an new MemoryCache -func NewCache(maxCount int) *MemoryCache { - return &MemoryCache{ - cacheHolder: make(map[string]string, maxCount), - MaxCount: maxCount, - } -} - -// Add an new cache item -func (cache *MemoryCache) Add(cacheKey string, cacheData string) { - cache.Lock() - defer cache.Unlock() - - if len(cache.cacheKeys) >= cache.MaxCount && len(cache.cacheKeys) > 1 { - delete(cache.cacheHolder, cache.cacheKeys[0]) // delete first item - cache.cacheKeys = append(cache.cacheKeys[1:]) // pop first one - } - - cache.cacheHolder[cacheKey] = cacheData - cache.cacheKeys = append(cache.cacheKeys, cacheKey) -} - -// Get a cache item by its key -func (cache *MemoryCache) Get(cacheKey string) string { - cache.Lock() - defer cache.Unlock() - - return cache.cacheHolder[cacheKey] -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/base_options.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/base_options.go deleted file mode 100644 index 64e07aa82ea2..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/base_options.go +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 auth - -// AuthOptionsProvider presents the base of an auth options implementation -type AuthOptionsProvider interface { - GetIdentityEndpoint() string - GetProjectId() string - GetDomainId() string -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token/tokenID_options.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token/tokenID_options.go deleted file mode 100644 index 81ac1d4f86cd..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token/tokenID_options.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 token - -// TokenIdOptions presents the required information for token ID auth -type TokenIdOptions struct { - // IdentityEndpoint specifies the HTTP endpoint that is required to work with - // the Identity API of the appropriate version. While it's ultimately needed by - // all of the identity services, it will often be populated by a provider-level - // function. - // - // The IdentityEndpoint is typically referred to as the "auth_url" or - // "OS_AUTH_URL" in the information provided by the cloud operator. - IdentityEndpoint string `json:"-" required:"true"` - - // AuthToken allows users to authenticate (possibly as another user) with an - // authentication token ID. - AuthToken string `json:"-"` - - // user project id - ProjectID string - - DomainID string `json:"-" required:"true"` -} - -// GetIdentityEndpoint Implements the method of AuthOptionsProvider -func (opts TokenIdOptions) GetIdentityEndpoint() string { - return opts.IdentityEndpoint -} - -//GetProjectId Implements the method of AuthOptionsProvider -func (opts TokenIdOptions) GetProjectId() string { - return opts.ProjectID -} - -// GetDomainId Implements the method of AuthOptionsProvider -func (opts TokenIdOptions) GetDomainId() string { - return opts.DomainID -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token/token_options.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token/token_options.go deleted file mode 100644 index e385b0311b60..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token/token_options.go +++ /dev/null @@ -1,462 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 token providers functions for initial http request body before request cloud. -*/ -package token - -import ( - "fmt" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -/* -TokenOptions - AuthOptions stores information needed to authenticate to an OpenStack Cloud. -You can populate one manually, or use a provider's AuthOptionsFromEnv() function -to read relevant information from the standard environment variables. Pass one -to a provider's AuthenticatedClient function to authenticate and obtain a -ProviderClient representing an active session on that provider. - -Its fields are the union of those recognized by each identity implementation and -provider. - -An example of manually providing authentication information: - - opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - Username: "{username}", - Password: "{password}", - TenantID: "{tenant_id}", - } - - provider, err := openstack.AuthenticatedClient(opts) - -An example of using AuthOptionsFromEnv(), where the environment variables can -be read from a file, such as a standard openrc file: - - opts, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.AuthenticatedClient(opts) -*/ -type TokenOptions struct { - // IdentityEndpoint specifies the HTTP endpoint that is required to work with - // the Identity API of the appropriate version. While it's ultimately needed by - // all of the identity services, it will often be populated by a provider-level - // function. - // - // The IdentityEndpoint is typically referred to as the "auth_url" or - // "OS_AUTH_URL" in the information provided by the cloud operator. - IdentityEndpoint string `json:"-"` - - // Username is required if using Identity V2 API. Consult with your provider's - // control panel to discover your account's username. In Identity V3, either - // UserID or a combination of Username and DomainID or DomainName are needed. - Username string `json:"username,omitempty"` - UserID string `json:"-"` - - Password string `json:"password,omitempty"` - - // At most one of DomainID and DomainName must be provided if using Username - // with Identity V3. Otherwise, either are optional. - DomainID string `json:"-"` - DomainName string `json:"name,omitempty"` - - // The TenantID and TenantName fields are optional for the Identity V2 API. - // The same fields are known as project_id and project_name in the Identity - // V3 API, but are collected as TenantID and TenantName here in both cases. - // Some providers allow you to specify a TenantName instead of the TenantId. - // Some require both. Your provider's authentication policies will determine - // how these fields influence authentication. - // If DomainID or DomainName are provided, they will also apply to TenantName. - // It is not currently possible to authenticate with Username and a Domain - // and scope to a Project in a different Domain by using TenantName. To - // accomplish that, the ProjectID will need to be provided as the TenantID - // option. - TenantID string `json:"tenantId,omitempty"` - TenantName string `json:"tenantName,omitempty"` - - ProjectID string `json:"project_id,omitempty"` - ProjectName string `json:"project_name,omitempty"` - - // AllowReauth should be set to true if you grant permission for Gophercloud to - // cache your credentials in memory, and to allow Gophercloud to attempt to - // re-authenticate automatically if/when your token expires. If you set it to - // false, it will not cache these settings, but re-authentication will not be - // possible. This setting defaults to false. - // - // NOTE: The reauth function will try to re-authenticate endlessly if left - // unchecked. The way to limit the number of attempts is to provide a custom - // HTTP client to the provider client and provide a transport that implements - // the RoundTripper interface and stores the number of failed retries. For an - // example of this, see here: - // https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311 - AllowReauth bool `json:"-"` - - // TokenID allows users to authenticate (possibly as another user) with an - // authentication token ID. - TokenID string `json:"-"` -} - -// GetIdentityEndpoint Implements the method of AuthOptionsProvider -func (opts TokenOptions) GetIdentityEndpoint() string { - return opts.IdentityEndpoint -} - -// GetProjectId gets project id -func (opts TokenOptions) GetProjectId() string { - if opts.ProjectID != "" { - return opts.ProjectID - } - return opts.TenantID -} - -// GetDomainId gets domain id -func (opts TokenOptions) GetDomainId() string { - return opts.DomainID -} - -// ToTokenV2CreateMap allows TokenOptions to satisfy the AuthOptionsBuilder -// interface in the v2 tokens package -func (opts TokenOptions) ToTokenV2CreateMap() (map[string]interface{}, error) { - // Populate the request map. - authMap := make(map[string]interface{}) - - if opts.Username != "" { - if opts.Password != "" { - authMap["passwordCredentials"] = map[string]interface{}{ - "username": opts.Username, - "password": opts.Password, - } - } else { - message := fmt.Sprintf(huaweicloudsdk.CEMissingInputMessage, "Password") - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEMissingInputCode, message) - return nil, err - //return nil, ErrMissingInput{Argument: "Password"} - } - } else if opts.TokenID != "" { - authMap["token"] = map[string]interface{}{ - "id": opts.TokenID, - } - } else { - message := fmt.Sprintf(huaweicloudsdk.CEMissingInputMessage, "Username") - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEMissingInputCode, message) - return nil, err - //return nil, ErrMissingInput{Argument: "Username"} - } - - if opts.TenantID != "" { - authMap["tenantId"] = opts.TenantID - } - if opts.TenantName != "" { - authMap["tenantName"] = opts.TenantName - } - - return map[string]interface{}{"auth": authMap}, nil -} - -// ToTokenV3CreateMap ... -func (opts *TokenOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { - type domainReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - } - - type projectReq struct { - Domain *domainReq `json:"domain,omitempty"` - Name *string `json:"name,omitempty"` - ID *string `json:"id,omitempty"` - } - - type userReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Password string `json:"password"` - Domain *domainReq `json:"domain,omitempty"` - } - - type passwordReq struct { - User userReq `json:"user"` - } - - type tokenReq struct { - ID string `json:"id"` - } - - type identityReq struct { - Methods []string `json:"methods"` - Password *passwordReq `json:"password,omitempty"` - Token *tokenReq `json:"token,omitempty"` - } - - type authReq struct { - Identity identityReq `json:"identity"` - } - - type request struct { - Auth authReq `json:"auth"` - } - - // Populate the request structure based on the provided arguments. Create and return an error - // if insufficient or incompatible information is present. - var req request - - if opts.Password == "" { - if opts.TokenID != "" { - // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication - // parameters. - if opts.Username != "" { - //return nil, ErrUsernameWithToken{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "Username may not be provided when authenticating with a TokenID") - return nil, err - } - if opts.UserID != "" { - //return nil, ErrUserIDWithToken{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "UserID may not be provided when authenticating with a TokenID") - return nil, err - } - if opts.DomainID != "" { - //return nil, ErrDomainIDWithToken{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "DomainID may not be provided when authenticating with a TokenID") - return nil, err - } - if opts.DomainName != "" { - //return nil, ErrDomainNameWithToken{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "DomainName may not be provided when authenticating with a TokenID") - return nil, err - } - - // Configure the request for Token authentication. - req.Auth.Identity.Methods = []string{"token"} - req.Auth.Identity.Token = &tokenReq{ - ID: opts.TokenID, - } - } else { - // If no password or token ID are available, authentication can't continue. - //return nil, ErrMissingPassword{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide a password to authenticate") - return nil, err - } - } else { - // Password authentication. - req.Auth.Identity.Methods = []string{"password"} - - // At least one of Username and UserID must be specified. - if opts.Username == "" && opts.UserID == "" { - //return nil, ErrUsernameOrUserID{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "Exactly one of Username and UserID must be provided for password authentication") - return nil, err - } - - if opts.Username != "" { - // If Username is provided, UserID may not be provided. - if opts.UserID != "" { - //return nil, ErrUsernameOrUserID{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "Exactly one of Username and UserID must be provided for password authentication") - return nil, err - } - - // Either DomainID or DomainName must also be specified. - if opts.DomainID == "" && opts.DomainName == "" { - //return nil, ErrDomainIDOrDomainName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide exactly one of DomainID or DomainName to authenticate by Username") - return nil, err - } - - if opts.DomainID != "" { - if opts.DomainName != "" { - //return nil, ErrDomainIDOrDomainName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide exactly one of DomainID or DomainName to authenticate by Username") - return nil, err - } - - // Configure the request for Username and Password authentication with a DomainID. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &opts.Username, - Password: opts.Password, - Domain: &domainReq{ID: &opts.DomainID}, - }, - } - } - - if opts.DomainName != "" { - // Configure the request for Username and Password authentication with a DomainName. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &opts.Username, - Password: opts.Password, - Domain: &domainReq{Name: &opts.DomainName}, - }, - } - } - } - - if opts.UserID != "" { - // If UserID is specified, neither DomainID nor DomainName may be. - if opts.DomainID != "" { - //return nil, ErrDomainIDWithUserID{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "DomainID may not be provided when authenticating with a UserID") - return nil, err - } - if opts.DomainName != "" { - //return nil, ErrDomainNameWithUserID{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "DomainName may not be provided when authenticating with a UserID") - return nil, err - } - - // Configure the request for UserID and Password authentication. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ID: &opts.UserID, Password: opts.Password}, - } - } - } - - b, err := huaweicloudsdk.BuildRequestBody(req, "") - if err != nil { - return nil, err - } - - if len(scope) != 0 { - b["auth"].(map[string]interface{})["scope"] = scope - } - - return b, nil -} - -// ToTokenV3ScopeMap ... -func (opts *TokenOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - - var scope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string - } - - //init project token scope - if opts.ProjectID != "" { - scope.ProjectID = opts.ProjectID - } else { - if opts.ProjectName != "" { - scope.ProjectName = opts.ProjectName - scope.DomainID = opts.DomainID - scope.DomainName = opts.DomainName - } - } - - if opts.TenantID != "" { - scope.ProjectID = opts.TenantID - } else { - if opts.TenantName != "" { - scope.ProjectName = opts.TenantName - scope.DomainID = opts.DomainID - scope.DomainName = opts.DomainName - } - } - - if scope.ProjectName != "" { - // ProjectName provided: either DomainID or DomainName must also be supplied. - // ProjectID may not be supplied. - if scope.DomainID == "" && scope.DomainName == "" { - //return nil, ErrScopeDomainIDOrDomainName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName") - return nil, err - } - if scope.ProjectID != "" { - //return nil, ErrScopeProjectIDOrProjectName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide at most one of ProjectID or ProjectName in a Scope") - return nil, err - } - - if scope.DomainID != "" { - // ProjectName + DomainID - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &scope.ProjectName, - "domain": map[string]interface{}{"id": &scope.DomainID}, - }, - }, nil - } - - if scope.DomainName != "" { - // ProjectName + DomainName - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &scope.ProjectName, - "domain": map[string]interface{}{"name": &scope.DomainName}, - }, - }, nil - } - } else if scope.ProjectID != "" { - // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. - if scope.DomainID != "" || scope.DomainName != "" { - //return nil, ErrScopeProjectIDAlone{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "ProjectID must be supplied alone in a Scope") - return nil, err - } - // if scope.DomainName != "" { - // return nil, ErrScopeProjectIDAlone{} - // } - - // ProjectID - return map[string]interface{}{ - "project": map[string]interface{}{ - "id": &scope.ProjectID, - }, - }, nil - } - - scope.DomainID = opts.DomainID - - if scope.DomainID != "" { - // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. - //if scope.DomainName != "" { - // //return nil, ErrScopeDomainIDOrDomainName{} - // - // err := gophercloud.NewSystemCommonError("Com.2000", "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName") - // return nil, err - //} - - // DomainID - return map[string]interface{}{ - "domain": map[string]interface{}{ - "id": &scope.DomainID, - }, - }, nil - } - - return nil, nil -} - -// CanReauth ... -func (opts TokenOptions) CanReauth() bool { - return opts.AllowReauth -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/config.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/config.go deleted file mode 100644 index e0688418d35d..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/config.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "net/http" - "time" -) - -// Config define the configs parameter of the provider client . -type Config struct { - // Timeout specifies a time limit for requests made by this - // Client. The timeout includes connection time, any - // redirects, and reading the response body. The timer remains - // running after Get, Head, Post, or Do return and will - // interrupt reading of the Response.Body. - // - // A Timeout of zero means no timeout. - Timeout time.Duration `default:"10000000000"` - // Transport specifies the mechanism by which individual - // HTTP requests are made. - // If nil, DefaultTransport is used. - HttpTransport *http.Transport `default:""` - //AutoRetry bool `default:"true"` - //MaxRetryTime int `default:"3"` - //UserAgent string `default:""` - //EnableAsync bool `default:"false"` - //MaxTaskQueueSize int `default:"1000"` - //GoRoutinePoolSize int `default:"5"` -} - -//NewConfig return Config instance with its default tag. -func NewConfig() (config *Config) { - config = &Config{} - InitStructWithDefaultTag(config) - return -} - -// WithTimeout customizes the http connection timeout. -func (c *Config) WithTimeout(timeout time.Duration) *Config { - c.Timeout = timeout - return c -} - -// WithHttpTransport customizes the http transport. -func (c *Config) WithHttpTransport(httpTransport *http.Transport) *Config { - c.HttpTransport = httpTransport - return c -} - -/* -func (c *Config) WithAutoRetry(isAutoRetry bool) *Config { - c.AutoRetry = isAutoRetry - return c -} - -func (c *Config) WithMaxRetryTime(maxRetryTime int) *Config { - c.MaxRetryTime = maxRetryTime - return c -} - -func (c *Config) WithEnableAsync(isEnableAsync bool) *Config { - c.EnableAsync = isEnableAsync - return c -} - -func (c *Config) WithMaxTaskQueueSize(maxTaskQueueSize int) *Config { - c.MaxTaskQueueSize = maxTaskQueueSize - return c -} - -func (c *Config) WithGoRoutinePoolSize(goRoutinePoolSize int) *Config { - c.GoRoutinePoolSize = goRoutinePoolSize - return c -} -func (c *Config) WithUserAgent(userAgent string) *Config { - c.UserAgent = userAgent - return c -} - -*/ diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/endpoint_search.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/endpoint_search.go deleted file mode 100644 index c90258597e57..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/endpoint_search.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -// Availability indicates to whom a specific service endpoint is accessible: -// the internet at large, internal networks only, or only to administrators. -// Different identity services use different terminology for these. Identity v2 -// lists them as different kinds of URLs within the service catalog ("adminURL", -// "internalURL", and "publicURL"), while v3 lists them as "Interfaces" in an -// endpoint's response. -type Availability string - -const ( - // AvailabilityAdmin indicates that an endpoint is only available to - // administrators. - AvailabilityAdmin Availability = "admin" - - // AvailabilityPublic indicates that an endpoint is available to everyone on - // the internet. - AvailabilityPublic Availability = "public" - - // AvailabilityInternal indicates that an endpoint is only available within - // the cluster's internal network. - AvailabilityInternal Availability = "internal" -) - -// EndpointOpts specifies search criteria used by queries against an -// OpenStack service catalog. The options must contain enough information to -// unambiguously identify one, and only one, endpoint within the catalog. -// -// Usually, these are passed to service client factory functions in a provider -// package, like "openstack.NewComputeV2()". -type EndpointOpts struct { - // Type [required] is the service type for the client (e.g., "compute", - // "object-store"). Generally, this will be supplied by the service client - // function, but a user-given value will be honored if provided. - Type string - - // Name [optional] is the service name for the client (e.g., "nova") as it - // appears in the service catalog. Services can have the same Type but a - // different Name, which is why both Type and Name are sometimes needed. - Name string - - // Region [required] is the geographic region in which the endpoint resides, - // generally specifying which datacenter should house your resources. - // Required only for services that span multiple regions. - Region string - - // Availability [optional] is the visibility of the endpoint to be returned. - // Valid types include the constants AvailabilityPublic, AvailabilityInternal, - // or AvailabilityAdmin from this package. - // - // Availability is not required, and defaults to AvailabilityPublic. Not all - // providers or services offer all Availability options. - Availability Availability -} - -/* -EndpointLocator is an internal function to be used by provider implementations. - -It provides an implementation that locates a single endpoint from a service -catalog for a specific ProviderClient based on user-provided EndpointOpts. The -provider then uses it to discover related ServiceClients. -*/ -type EndpointLocator func(EndpointOpts) (string, error) - -// ApplyDefaults is an internal method to be used by provider implementations. -// -// It sets EndpointOpts fields if not already set, including a default type. -// Currently, EndpointOpts.Availability defaults to the public endpoint. -func (eo *EndpointOpts) ApplyDefaults(t string) { - if eo.Type == "" { - eo.Type = t - } - if eo.Availability == "" { - eo.Availability = AvailabilityPublic - } -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/errors.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/errors.go deleted file mode 100644 index d9b0c261f7e2..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/errors.go +++ /dev/null @@ -1,409 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "encoding/json" - "fmt" - "regexp" - "strconv" - "strings" -) - -//Define Service error information. -const ( - //ECS - EcsAuthRequired = "Authentication required" - EcsPoilcyNotAllow = "Policy doesn't allow .*. to be performed" - EcsTokenRoleEmpty = "token role is empty, forbidden to perform this action" - EcsTokenRoleForbidden = "token role * is forbidden to perform this action" - EcsErrorRoleToPerform = "do not have the required roles, forbbiden to perform this action" - EcsQuotaExceeded = "Quota exceeded for instances" - EcsPortNumberExceed = "Maximum number of ports exceeded" - EcsVolumeNumberOver = "Volume number is over limit" - EcsBlockImageNotFound = "Block Device Mapping is Invalid: failed to get image.*." - EcsImageNotFound = "Image * could not be found." - EcsFlavorNotFound = "Flavor .*. could not be found" - EcsNetworkNotFound = "Network.*.could not be found" - EcsBlockDevInvalid = "Block Device Mapping is Invalid" - EcsAZUnavailable = "The requested availability zone is not available" - EcsSecurityGroupNotFound = "Security group .*. not found" - EcsKeyPairNotFound = "Keypair .*. not found for user *" - EcsInstanceGroupNotFound = "Instance group .*. could not be found" - EcsInvalidMetadata = "Invalid metadata.*" - EcsUserDataBase64 = "User data needs to be valid base 64" - EcsUserDataTooLarge = "User data too large. User data must be no larger than .*" - EcsInstanceDiskExceed = "The created instance's disk would be too small" - EcsFlavorMemoryNotEnough = "Flavor's memory is too small for requested image" - EcsInstanceNotFound = "Instance .*. could not be found" - EcsInstanceIsLocked = "Instance .*. is locked" - EcsInstCantBeOperated = "Cannot .*. instance .*. while it is in .*" - EcsUnexpectedApiERROR = "Unexpected API Error" - EcsServerCantComply = "The server could not comply with the request since it is either malformed.*." - EcsInvalidFlavorRef = "Invalid flavorRef provided" - EcsInvalidKeyName = "Invalid key_name provided" - EcsInvalidInputField = "Invalid input for field/attribute" - EcsResourceSoldOut = "Instance resource is temporarily sold out." - - //IMS - Ims0027NoImageFoundWithId = "No image found with ID" - Ims0144FailedFindImage = "Failed to find image" - - //ELB - ELB2001AdminStateUpFalse = "Admin_state_up is not allowed with False" - ELB2002IpNotValid = "IP address .*. is not a valid IP for the specified subnet." - ELB2003PoolNotFound = "pool .*. could not be found" - ELB2004MemberNotSupportPort = "Member not support protocol port *" - ELB2005SubnetMismatch = "Router of member's subnet .*. and router of loadbalancer's subnet .*. mismatch" - ELB2006IpPortAlreadyPresent = "Member with address .*. and protocol_port .*. already present in pool .*." - ELB2007MemberNotFound = "member .*. could not be found" - - ELB6101QuotaExceeded = "Quota exceeded for resources: \\['listener'\\]" - ELB2541QuotaExceeded = "Quota exceeded for resources: \\['pool'\\]" - ELBb015QuotaExceeded = "Quota exceeded for resources: \\['l7policy'\\]" - ELB1071QuotaExceeded = "Quota exceeded for resources: \\['loadbalancer'\\]" -) - -//Common Error. -const ( - //Com1000 - CEMissingInputCode = "Com.1000" //client error - CEMissingInputMessage = "Missing input for argument [%s]" - - //Com1001 - CEStreamControlApiCode = "Com.1001" //server error - CEStreamControlApiMessage = "The maximum request receiving rate is exceeded" - - //Com1002 - CEInvalidInputCode = "Com.1002" //client error - CEInvalidInputMessage = "Invalid input provided for argument [%s]" - - CEOptionTypeNotStructCode = "Com.1002" //client error - CEOptionTypeNotStructMessage = "Options type is not a struct" - - //Com1003 - CEResourceNotFoundCode = "Com.1003" //client error - CEResourceNotFoundMessage = "Unable to find %s with name %s" - - CEMultipleResourcesFoundCode = "Com.1003" //client error - CEMultipleResourcesFoundMessage = "Found %d %ss matching %s" - - CEErrUnexpectedTypeCode = "Com.1003" //client error - CEErrUnexpectedTypeMessage = "Expected %s but got %s" - - //Com1004 - CENoClientProvidedCode = "Com.1004" //client error - CENoClientProvidedMessage = "A service client must be provided to find a resource ID by name" - - CENoEndPointInCatalogCode = "Com.1004" //client error - CENoEndPointInCatalogMessage = "No suitable endpoint could be found in the service catalog." - - //Com1005 - CEApiNotFoundCode = "Com.1005" //server error - CEApiNotFoundMessage = "API not found" - - //1006 - CETimeoutErrorCode = "Com.1006" //client error - CETimeoutErrorMessage = "The request timed out %s times(%s for retry), perhaps we should have the threshold raised a little?" - - CEReauthExceedCode = "Com.1006" //client error - CEReauthExceedMessage = "Tried to re-authenticate 3 times with no success." - - CEReauthFuncErrorCode = "Com.1006" //client error - CEReauthFuncErrorMessage = "Get reauth function error [%s]" - - //Com2000 - //其他非典型错误,不再统一定义。 -) - -// UnifiedError Unified definition of backend errors. -type UnifiedError struct { - ErrCode interface{} `json:"code"` - ErrMessage string `json:"message"` -} - -// NewSystemCommonError Initialize SDK client error. -func NewSystemCommonError(code, message string) error { - return &UnifiedError{ - ErrCode: code, - ErrMessage: message, - } -} - -// NewSystemServerError Handle background API error codes. -func NewSystemServerError(httpStatus int, responseContent string) error { - //e.Body {"error": {"message": "instance is not shutoff.","code": "IMG.0008"}} - return ParseSeverError(httpStatus, responseContent) -} - -// Error Implement the Error() interface. -func (e UnifiedError) Error() string { - return fmt.Sprintf("{\"ErrorCode\":\"%s\",\"Message\":\"%s\"}", e.ErrCode, e.ErrMessage) -} - -// ErrorCode Error code converted to string type. -func (e UnifiedError) ErrorCode() string { - if s, ok := e.ErrCode.(string); ok { - return s - } - - if i, ok := e.ErrCode.(int); ok { - return fmt.Sprint(i) - } - - return "" -} - -// Message Return error message. -func (e UnifiedError) Message() string { - return e.ErrMessage -} - -// OneLevelError Define the error code structure and match the error code of one layer of json structure -type OneLevelError struct { - Message string - RequestID string - ErrCode string `json:"error_code"` - ErrMsg string `json:"error_msg"` - Code string `json:"code"` -} - -// ParseSeverError This function uses json serialization to parse background API error codes. -func ParseSeverError(httpStatus int, responseContent string) error { - //一层结构如下: - //第一种:{"error_msg": "Instance *89973356-f733-418b-95b2-f6fc27244f18 could not be found.","err_code": 404} - //第二种:{"message": "Instance *89973356-f733-418b-95b2-f6fc27244f18 could not be found.","code": "VPC.0101"} - //第三种:html 页面,返回字符串形式,走正则匹配错误码。 - - //两层结构如下: - //{"itemNotFound": {"message": "Instance *89973356-f733-418b-95b2-f6fc27244f18 could not be found.", "code": 404}} - //{"error": {"message": "instance is not shutoff.","code": "IMG.0008"}} - var olErr OneLevelError - var errMsg = make(map[string]UnifiedError) - var isDevApi bool //是否为自研api接口 - var errCode string - message := responseContent - - err := json.Unmarshal([]byte(responseContent), &errMsg) - if err != nil { //一层结构错误 - err1 := json.Unmarshal([]byte(responseContent), &olErr) - if err1 != nil { - errCode = MatchErrorCode(httpStatus, message) - message = responseContent - } else { - if olErr.Code == "" && olErr.ErrCode == "" { - errCode = MatchErrorCode(httpStatus, olErr.Message) - message = olErr.Message - } else { - if olErr.Code != "" { - errCode = olErr.Code - message = olErr.Message - } - if olErr.ErrCode != "" { - errCode = olErr.ErrCode - message = olErr.ErrMsg - } - } - } - } else { //两层结构错误 - for _, em := range errMsg { - message = em.ErrMessage - - /* - 自研api的code字段为string且包含'.',否则为原生api, - 原生api也可能是string类型,但是不包含'.' - 原生api的errCode走解析流程这里不需要赋值 - 自研api的code示例:"IMG.0144" - 原生api的code示例:400或者"400" - */ - switch em.ErrCode.(type) { - case string: - if strings.Contains(em.ErrCode.(string), ".") { - isDevApi = true - errCode = em.ErrCode.(string) - } else { - isDevApi = false - } - default: - isDevApi = false - } - } - - //原生api接口走解析流程 - if !isDevApi { - errCode = MatchErrorCode(httpStatus, message) - } - } - - return &UnifiedError{ - ErrCode: errCode, - ErrMessage: message, - } -} - -// MatchErrorCode Match the error code according to the error message -func MatchErrorCode(httpStatus int, message string) string { - //common error - if ok, _ := regexp.MatchString(CEApiNotFoundMessage, message); ok { - return CEApiNotFoundCode - } - if ok, _ := regexp.MatchString(CEStreamControlApiMessage, message); ok { - return CEStreamControlApiCode - } - - //ECS error - if ok, _ := regexp.MatchString(EcsAuthRequired, message); ok { - return "Ecs.1499" - } - if ok, _ := regexp.MatchString(EcsPoilcyNotAllow, message); ok { - return "Ecs.1500" - } - if ok, _ := regexp.MatchString(EcsTokenRoleEmpty, message); ok { - return "Ecs.1500" - } - if ok, _ := regexp.MatchString(EcsTokenRoleForbidden, message); ok { - return "Ecs.1500" - } - if ok, _ := regexp.MatchString(EcsErrorRoleToPerform, message); ok { - return "Ecs.1500" - } - if ok, _ := regexp.MatchString(EcsQuotaExceeded, message); ok { - return "Ecs.1501" - } - if ok, _ := regexp.MatchString(EcsPortNumberExceed, message); ok { - return "Ecs.1502" - } - if ok, _ := regexp.MatchString(EcsVolumeNumberOver, message); ok { - return "Ecs.1503" - } - if ok, _ := regexp.MatchString(EcsBlockImageNotFound, message); ok { - return "Ecs.1511" - } - if ok, _ := regexp.MatchString(EcsImageNotFound, message); ok { - return "Ecs.1511" - } - if ok, _ := regexp.MatchString(EcsFlavorNotFound, message); ok { - return "Ecs.1512" - } - if ok, _ := regexp.MatchString(EcsInvalidFlavorRef, message); ok { - return "Ecs.1512" - } - if ok, _ := regexp.MatchString(EcsNetworkNotFound, message); ok { - return "Ecs.1513" - } - if ok, _ := regexp.MatchString(EcsBlockDevInvalid, message); ok { - return "Ecs.1514" - } - if ok, _ := regexp.MatchString(EcsAZUnavailable, message); ok { - return "Ecs.1515" - } - if ok, _ := regexp.MatchString(EcsSecurityGroupNotFound, message); ok { - return "Ecs.1516" - } - if ok, _ := regexp.MatchString(EcsKeyPairNotFound, message); ok { - return "Ecs.1517" - } - if ok, _ := regexp.MatchString(EcsInvalidKeyName, message); ok { - return "Ecs.1517" - } - if ok, _ := regexp.MatchString(EcsInstanceGroupNotFound, message); ok { - return "Ecs.1518" - } - if ok, _ := regexp.MatchString(EcsInvalidMetadata, message); ok { - return "Ecs.1519" - } - if ok, _ := regexp.MatchString(EcsInvalidInputField, message); ok { - return "Ecs.1519" - } - if ok, _ := regexp.MatchString(EcsUserDataBase64, message); ok { - return "Ecs.1520" - } - if ok, _ := regexp.MatchString(EcsUserDataTooLarge, message); ok { - return "Ecs.1521" - } - if ok, _ := regexp.MatchString(EcsInstanceDiskExceed, message); ok { - return "Ecs.1522" - } - if ok, _ := regexp.MatchString(EcsFlavorMemoryNotEnough, message); ok { - return "Ecs.1523" - } - if ok, _ := regexp.MatchString(EcsResourceSoldOut, message); ok { - return "Ecs.1524" - } - if ok, _ := regexp.MatchString(EcsInstanceNotFound, message); ok { - return "Ecs.1544" - } - if ok, _ := regexp.MatchString(EcsInstanceIsLocked, message); ok { - return "Ecs.1545" - } - if ok, _ := regexp.MatchString(EcsInstCantBeOperated, message); ok { - return "Ecs.1546" - } - if ok, _ := regexp.MatchString(EcsServerCantComply, message); ok { - return "Ecs.1599" - } - if ok, _ := regexp.MatchString(EcsUnexpectedApiERROR, message); ok { - return "Ecs.1599" - } - - //IMS error - if ok, _ := regexp.MatchString(Ims0027NoImageFoundWithId, message); ok { - return "IMG.0027" - } - if ok, _ := regexp.MatchString(Ims0144FailedFindImage, message); ok { - return "IMG.0144" - } - - //ELB error - if ok, _ := regexp.MatchString(ELB2001AdminStateUpFalse, message); ok { - return "ELB.2001" - } - if ok, _ := regexp.MatchString(ELB2002IpNotValid, message); ok { - return "ELB.2002" - } - if ok, _ := regexp.MatchString(ELB2003PoolNotFound, message); ok { - return "ELB.2003" - } - if ok, _ := regexp.MatchString(ELB2004MemberNotSupportPort, message); ok { - return "ELB.2004" - } - if ok, _ := regexp.MatchString(ELB2005SubnetMismatch, message); ok { - return "ELB.2005" - } - if ok, _ := regexp.MatchString(ELB2006IpPortAlreadyPresent, message); ok { - return "ELB.2006" - } - if ok, _ := regexp.MatchString(ELB2007MemberNotFound, message); ok { - return "ELB.2007" - } - - if ok, _ := regexp.MatchString(ELB6101QuotaExceeded, message); ok { - return "ELB.6101" - } - if ok, _ := regexp.MatchString(ELB2541QuotaExceeded, message); ok { - return "ELB.2541" - } - if ok, _ := regexp.MatchString(ELBb015QuotaExceeded, message); ok { - return "ELB.B015" - } - if ok, _ := regexp.MatchString(ELB1071QuotaExceeded, message); ok { - return "ELB.1071" - } - - //没匹配上,用http状态码做error code - return "Com." + strconv.Itoa(httpStatus) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/internal/util.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/internal/util.go deleted file mode 100644 index fb43c581ca09..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/internal/util.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 internal - -import ( - "reflect" - "strings" -) - -// RemainingKeys will inspect a struct and compare it to a map. Any struct -// field that does not have a JSON tag that matches a key in the map or -// a matching lower-case field in the map will be returned as an extra. -// -// This is useful for determining the extra fields returned in response bodies -// for resources that can contain an arbitrary or dynamic number of fields. -func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) { - extras = make(map[string]interface{}) - for k, v := range m { - extras[k] = v - } - - valueOf := reflect.ValueOf(s) - typeOf := reflect.TypeOf(s) - for i := 0; i < valueOf.NumField(); i++ { - field := typeOf.Field(i) - - lowerField := strings.ToLower(field.Name) - delete(extras, lowerField) - - if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" { - delete(extras, tagValue) - } - } - - return -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/requests.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/requests.go deleted file mode 100644 index b3de899f6290..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/requests.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 clusters - -import ( - "fmt" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "net/http" -) - -// GetCCECluster calls CCE REST API to get cce cluster's information. -func GetCCECluster(client *huaweicloudsdk.ServiceClient, clusterId string) (r GetCCEClusterResult) { - clusterURL := getClusterURL(client, clusterId) - _, r.Err = client.Get(clusterURL, &r.Body, nil) - return -} - -// GetNodePools calls CCE REST API to get the information of all node pools in a designated cluster. -func GetNodePools(client *huaweicloudsdk.ServiceClient, clusterId string) (r GetCCENodePoolsResult) { - nodePoolsURL := getNodePoolsURL(client, clusterId) - _, r.Err = client.Get(nodePoolsURL, &r.Body, nil) - return -} - -// DeleteNode calls CCE REST API to delete a node with UID of nodeId in a designated cluster. -func DeleteNode(client *huaweicloudsdk.ServiceClient, clusterId string, nodeId string) (r DeleteNodeResult) { - deleteNodeURL := deleteNodeURL(client, clusterId, nodeId) - _, r.Err = client.Delete(deleteNodeURL, nil) - return -} - -// UpdateOptsBuilder is used to build request body for updating the size of a node pool. -// It allows extensions to add additional parameters to the Update request. -type UpdateOptsBuilder interface { - ToClustersUpdateMap() (map[string]interface{}, error) -} - -// UpdateNodePool calls CCE REST API to update the size of a node pool with UID of nodepoolID in a designated cluster. -func UpdateNodePool(client *huaweicloudsdk.ServiceClient, clusterId string, nodepoolId string, opt UpdateOptsBuilder) (r UpdateResult) { - b, err := opt.ToClustersUpdateMap() - if err != nil { - r.Err = err - return r - } - - var result *http.Response - - result, r.Err = client.Put(updateNodePoolURL(client, clusterId, nodepoolId), b, &r.Body, &huaweicloudsdk.RequestOpts{ - OkCodes: []int{200, 202}, - }) - - if r.Err == nil { - r.Header = result.Header - } else { - fmt.Printf("Failed to Update NodePool Size huaweicloud cloud provider: %v\n", r.Err) - } - - return -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/results.go deleted file mode 100644 index 157294da2df4..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/results.go +++ /dev/null @@ -1,166 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 clusters - -import ( - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -// CCECluster CCE model -type CCECluster struct { - Kind string `json:"kind"` - APIVersion string `json:"apiVersion"` - Metadata Metadata `json:"metadata"` - Status Status `json:"status"` -} - -// NodePool Node pool model -type NodePool struct { - Kind string `json:"kind"` - APIVersion string `json:"apiVersion"` - Metadata Metadata `json:"metadata"` - Spec Spec `json:"spec"` - NodePoolStatus NodePoolStatus `json:"status"` -} - -// NodePools Node pools model -type NodePools struct { - Kind string `json:"kind"` - APIVersion string `json:"apiVersion"` - Items []NodePool `json:"items"` -} - -// CCENode Node model -type CCENode struct { - Kind string `json:"kind"` - APIVersion string `json:"apiVersion"` - Metadata Metadata `json:"metadata"` - Spec Spec `json:"spec"` - Status Status `json:"status"` -} - -// RequestBody Request body for updating a node pool -type RequestBody struct { - Metadata Metadata `json:"metadata"` - Spec Spec `json:"spec"` -} - -// Status "status" section for CCE Node -type Status struct { - Phase string `json:"phase"` - JobId string `json:"jobId"` - ServerId string `json:"serverId"` - PrivateIP string `json:"privateIP"` - PublicIP string `json:"publicIP"` -} - -// Metadata "metadata" section for CCE cluster and node pool -type Metadata struct { - Name string `json:"name"` - Uid string `json:"uid"` -} - -// Autoscaling "autoscaling" section in the request body of updating a node pool -type Autoscaling struct { - Enable bool `json:"enable"` - MinNodeCount int `json:"minNodeCount"` - MaxNodeCount int `json:"maxNodeCount"` -} - -// Spec "spec" section in the request body of updating a node pool -type Spec struct { - InitialNodeCount int `json:"initialNodeCount"` - Autoscaling Autoscaling `json:"autoscaling"` -} - -// NodePoolStatus "status" section of a node pool -type NodePoolStatus struct { - CurrentNode int `json:"currentNode"` - Phase string `json:"phase"` -} - -// ActionResult represents the result of server action operations, like reboot. -// Call its ExtractErr method to determine if the action succeeded or failed. -type ActionResult struct { - huaweicloudsdk.ErrResult -} - -// ChangeResult ... -type ChangeResult struct { - huaweicloudsdk.Result -} - -// GetCCEClusterResult for Cluster -type GetCCEClusterResult struct { - huaweicloudsdk.Result -} - -// Extract cluster info and error -func (r GetCCEClusterResult) Extract() (CCECluster, error) { - var res CCECluster - err := r.ExtractInto(&res) - return res, err -} - -// GetCCENodePoolsResult for NodePools -type GetCCENodePoolsResult struct { - huaweicloudsdk.Result -} - -// UpdateResult is the response of a Update operation. -type UpdateResult struct { - huaweicloudsdk.Result -} - -// Extract UUID and error -func (r UpdateResult) Extract() (string, error) { - var s struct { - UUID string - } - err := r.ExtractInto(&s) - return s.UUID, err -} - -// Extract node pools and error -func (r GetCCENodePoolsResult) Extract() (NodePools, error) { - var res NodePools - err := r.ExtractInto(&res) - return res, err -} - -// DeleteNodeResult is the error section in the result of deleting a node. -type DeleteNodeResult struct { - huaweicloudsdk.ErrResult -} - -// ToClustersUpdateMap is a method that has to be implemented by RequestBody for interface UpdateOptsBuilder. -// This method assembles a request body based on the contents of opts(type RequestBody). -func (opts RequestBody) ToClustersUpdateMap() (map[string]interface{}, error) { - return huaweicloudsdk.BuildRequestBody(opts, "") -} - -// ToClustersUpdateMap is a method that has to be implemented by Metadata for interface UpdateOptsBuilder. -// This method assembles a request body based on the contents of opts(type Metadata). -func (opts Metadata) ToClustersUpdateMap() (map[string]interface{}, error) { - return huaweicloudsdk.BuildRequestBody(opts, "") -} - -// ToClustersUpdateMap is a method that has to be implemented by Autoscaling for interface UpdateOptsBuilder. -// This method assembles a request body based on the contents of opts(type Autoscaling). -func (opts Autoscaling) ToClustersUpdateMap() (map[string]interface{}, error) { - return huaweicloudsdk.BuildRequestBody(opts, "") -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/urls.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/urls.go deleted file mode 100644 index 140019b604c9..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/cce/v3/clusters/urls.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 clusters - -import "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - -const ( - clusterDenoter = "clusters" - nodepoolDenoter = "nodepools" - nodeDenoter = "nodes" -) - -// getClusterURL returns a URL for getting the information of a cce cluster with designated clusterID. -// REST API: -// GET /api/v3/projects/{project_id}/clusters/{cluster_id} -// Example: -// https://cce.cn-north-1.myhuaweicloud.com/api/v3/projects/017a290a8242480e82de8db804c1718d/clusters/19d4f935-4c45-11ea-b2e7-0255ac101eee -func getClusterURL(sc *huaweicloudsdk.ServiceClient, clusterID string) string { - return sc.ServiceURL(clusterDenoter, clusterID) -} - -// getNodePoolsURL returns a URL for getting the information of all nodepools attached to a cce cluster with designated clusterID. -// REST API: -// GET /api/v3/projects/{project_id}/clusters/{cluster_id}/nodepools -// Example: -// https://cce.cn-north-4.myhuaweicloud.com/api/v3/projects/9071a38e7f6a4ba7b7bcbeb7d4ea6efc/clusters/25b884ab-623f-11ea-9981-0255ac101546/nodepools -func getNodePoolsURL(sc *huaweicloudsdk.ServiceClient, clusterID string) string { - return sc.ServiceURL(clusterDenoter, clusterID, nodepoolDenoter) -} - -// deleteNodeURL returns a URL for deleting a node with uid of nodeId in a cce cluster with clusterID. -// REST API: -// DELETE /api/v3/projects/{project_id}/clusters/{cluster_id}/nodes/{node_id} -// Example: -// https://cce.cn-north-4.myhuaweicloud.com/api/v3/projects/9071a38e7f6a4ba7b7bcbeb7d4ea6efc/clusters/25b884ab-623f-11ea-9981-0255ac101546/nodes/56a90712-6306-11ea-9981-0255ac101546 -func deleteNodeURL(sc *huaweicloudsdk.ServiceClient, clusterID string, nodeId string) string { - return sc.ServiceURL(clusterDenoter, clusterID, nodeDenoter, nodeId) -} - -// updateNodePoolURL returns a URL for updating the number of nodes in a node pool with id nodepoolID which attached to -// a cce cluster with id clusterID. -// REST API: -// PUT /api/v3/projects/{project_id}/clusters/{cluster_id}/nodepools/{nodepool_id} -// Example: -// PUT https://cce.cn-north-4.myhuaweicloud.com/api/v3/projects/9071a38e7f6a4ba7b7bcbeb7d4ea6efc/clusters/25b884ab-623f-11ea-9981-0255ac101546/nodepools/8445aeed-6240-11ea-a1c6-0255ac101d44 -func updateNodePoolURL(sc *huaweicloudsdk.ServiceClient, clusterID string, nodepoolID string) string { - return sc.ServiceURL(clusterDenoter, clusterID, nodepoolDenoter, nodepoolID) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/client.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/client.go deleted file mode 100644 index ab18ae1adf36..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/client.go +++ /dev/null @@ -1,827 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 openstack - -import ( - "fmt" - "net/http" - "net/url" - "reflect" - "regexp" - "strings" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth" - akskAuth "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk" - tokenAuth "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token" - tokens2 "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens" - tokens3 "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/utils" - - "encoding/json" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination" -) - -const ( - // v2 represents Keystone v2. - // It should never increase beyond 2.0. - v2 = "v2.0" - - // v3 represents Keystone v3. - // The version can be anything from v3 to v3.x. - v3 = "v3" -) - -// MyRoundTripper Rewrite RoundTrip to achieve reauth limit 3 times -type MyRoundTripper struct { - // http.RoundTripper interface. - rt http.RoundTripper - - // numReauthAttempts, http client Reauth times. - numReauthAttempts int -} - -//Initialize httpclient according to the config parameter. -func newHTTPClient(conf *huaweicloudsdk.Config) http.Client { - - hc := new(http.Client) - - if conf.Timeout > 0 { - hc.Timeout = conf.Timeout - } - - if conf.HttpTransport != nil { - hc.Transport = conf.HttpTransport - } else { - hc.Transport = &MyRoundTripper{ - rt: http.DefaultTransport, - } - } - - return *hc - -} - -//RoundTrip Implement the RoundTrip interface function.The reauth default setting is three times. -func (mrt *MyRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { - response, err := mrt.rt.RoundTrip(request) - if response == nil { - return nil, err - } - - if response.StatusCode == http.StatusUnauthorized { - if mrt.numReauthAttempts == 3 { - return response, fmt.Errorf("Tried to re-authenticate 3 times with no success.") - } - mrt.numReauthAttempts++ - } - - return response, err -} - -/* -AuthenticatedClientWithOptions Initialize the provider client based on the incoming config configuration,and returns -a Provider Client instance that's ready to request SDK service API. - -Example of Creating a Service Client with options - - conf := gophercloud.NewConfig() - ao, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.AuthenticatedClientWithOptions(ao,conf) - client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) -*/ -func AuthenticatedClientWithOptions(options auth.AuthOptionsProvider, conf *huaweicloudsdk.Config) (*huaweicloudsdk.ProviderClient, error) { - client, err := NewClient(options.GetIdentityEndpoint(), options.GetDomainId(), options.GetProjectId(), conf) - if err != nil { - return nil, err - } - - err = Authenticate(client, options) - if err != nil { - return nil, err - } - return client, nil -} - -/* -AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint -specified by the options, acquires a token, and returns a Provider Client -instance that's ready to operate. - -If the full path to a versioned identity endpoint was specified (example: -http://example.com:5000/v3), that path will be used as the endpoint to query. - -If a versionless endpoint was specified (example: http://example.com:5000/), -the endpoint will be queried to determine which versions of the identity service -are available, then chooses the most recent or most supported version. - -Example: - - ao, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.AuthenticatedClient(ao) - client, err := openstack.NewNetworkV2(client, EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) -*/ -func AuthenticatedClient(options auth.AuthOptionsProvider) (*huaweicloudsdk.ProviderClient, error) { - client, err := NewClient(options.GetIdentityEndpoint(), options.GetDomainId(), options.GetProjectId(), huaweicloudsdk.NewConfig()) - if err != nil { - return nil, err - } - - err = Authenticate(client, options) - if err != nil { - return nil, err - } - return client, nil -} - -/* -NewClient prepares an unauthenticated ProviderClient instance. -Most users will probably prefer using the AuthenticatedClient function -instead. - -This is useful if you wish to explicitly control the version of the identity -service that's used for authentication explicitly, for example. - -A basic example of using this would be: - - ao, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.NewClient(ao.IdentityEndpoint) - client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{}) -*/ -func NewClient(endpoint, domainID, projectID string, conf *huaweicloudsdk.Config) (*huaweicloudsdk.ProviderClient, error) { - if endpoint == "" { - message := fmt.Sprintf(huaweicloudsdk.CEMissingInputMessage, "IdentityEndpoint") - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEMissingInputCode, message) - return nil, err - } - u, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - - //if domainID == "" { - // message := fmt.Sprintf(gophercloud.CEMissingInputMessage, "domainID") - // err := gophercloud.NewSystemCommonError(gophercloud.CEMissingInputCode, message) - // return nil, err - //} - // - //if projectID == "" { - // message := fmt.Sprintf(gophercloud.CEMissingInputMessage, "projectID") - // err := gophercloud.NewSystemCommonError(gophercloud.CEMissingInputCode, message) - // return nil, err - //} - - u.RawQuery, u.Fragment = "", "" - - var base string - versionRe := regexp.MustCompile("v[0-9.]+/?") - if version := versionRe.FindString(u.Path); version != "" { - base = strings.Replace(u.String(), version, "", -1) - } else { - base = u.String() - } - - endpoint = huaweicloudsdk.NormalizeURL(endpoint) - base = huaweicloudsdk.NormalizeURL(base) - - p := new(huaweicloudsdk.ProviderClient) - p.IdentityBase = base - p.IdentityEndpoint = endpoint - p.DomainID = domainID - p.ProjectID = projectID - p.Conf = conf - p.UseTokenLock() - p.HTTPClient = newHTTPClient(conf) //自定义httpclient,限制reauth为3次 - - return p, nil -} - -// Authenticate or re-authenticate against the most recent identity service -// supported at the provided endpoint. -func Authenticate(client *huaweicloudsdk.ProviderClient, options auth.AuthOptionsProvider) error { - versions := []*utils.Version{ - {ID: v2, Priority: 20, Suffix: "/v2.0/"}, - {ID: v3, Priority: 30, Suffix: "/v3/"}, - } - - chosen, endpoint, err := utils.ChooseVersion(client, versions) - if err != nil { - return err - } - - authOptions, isTokenAuthOptions := options.(tokenAuth.TokenOptions) - - if isTokenAuthOptions { - switch chosen.ID { - case v2: - return tokenAuthV2(client, endpoint, authOptions, huaweicloudsdk.EndpointOpts{}) - case v3: - return tokenAuthV3(client, endpoint, &authOptions, huaweicloudsdk.EndpointOpts{}) - default: - // The switch statement must be out of date from the versions list. - return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) - } - } else { - akskOptions, isAKSKOptions := options.(akskAuth.AKSKOptions) - - if isAKSKOptions { - return akskAuthV3(client, endpoint, akskOptions, huaweicloudsdk.EndpointOpts{}) - } - TokenIdOptions, isTokenIdOptions := options.(tokenAuth.TokenIdOptions) - - if isTokenIdOptions { - return tokenIDAuthV3(client, endpoint, TokenIdOptions, huaweicloudsdk.EndpointOpts{}) - } - return fmt.Errorf("Unrecognized auth options provider: %s", reflect.TypeOf(options)) - } - -} - -func getEntryByServiceId(entries []tokens3.CatalogEntry, serviceId string) *tokens3.CatalogEntry { - if entries == nil { - return nil - } - - for idx := range entries { - if entries[idx].ID == serviceId { - return &entries[idx] - } - } - - return nil -} - -func tokenIDAuthV3(client *huaweicloudsdk.ProviderClient, endpoint string, tokenIdOptions tokenAuth.TokenIdOptions, eo huaweicloudsdk.EndpointOpts) error { - // Override the generated service endpoint with the one returned by the version endpoint. - - client.TokenID = tokenIdOptions.AuthToken - - v3Client, err := NewIdentityV3(client, eo) - if err != nil { - return err - } - - if endpoint != "" { - v3Client.Endpoint = endpoint - } - - var entries = make([]tokens3.CatalogEntry, 0, 1) - serviceListErr := services.List(v3Client, services.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - serviceLst, err := services.ExtractServices(page) - if err != nil { - return false, err - } - - for _, svc := range serviceLst { - entry := tokens3.CatalogEntry{ - Type: svc.Type, - Name: svc.Name, - ID: svc.ID, - } - entries = append(entries, entry) - } - - return true, nil - }) - - if serviceListErr != nil { - return serviceListErr - } - - endpointListErr := endpoints.List(v3Client, endpoints.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - endpointList, err := endpoints.ExtractEndpoints(page) - if err != nil { - return false, err - } - - for _, endpoint := range endpointList { - entry := getEntryByServiceId(entries, endpoint.ServiceID) - - if entry != nil { - entry.Endpoints = append(entry.Endpoints, tokens3.Endpoint{ - URL: strings.Replace(endpoint.URL, "$(tenant_id)s", tokenIdOptions.ProjectID, -1), - Region: endpoint.Region, - Interface: string(endpoint.Availability), - ID: endpoint.ID, - }) - } - } - - client.EndpointLocator = func(opts huaweicloudsdk.EndpointOpts) (string, error) { - return V3TokenIdExtractEndpointURL(&tokens3.ServiceCatalog{ - Entries: entries, - }, opts, tokenIdOptions) - } - - return true, nil - }) - - if endpointListErr != nil { - return endpointListErr - } - - if client.EndpointLocator == nil { - return huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CENoEndPointInCatalogCode, huaweicloudsdk.CENoEndPointInCatalogMessage) - } - return nil -} - -func akskAuthV3(client *huaweicloudsdk.ProviderClient, endpoint string, options akskAuth.AKSKOptions, eo huaweicloudsdk.EndpointOpts) error { - v3Client, err := NewIdentityV3(client, eo) - if err != nil { - return err - } - - if endpoint != "" { - v3Client.Endpoint = endpoint - } - - v3Client.AKSKOptions = options - - var entries = make([]tokens3.CatalogEntry, 0, 1) - serviceListErr := services.List(v3Client, services.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - serviceLst, err := services.ExtractServices(page) - if err != nil { - return false, err - } - - for _, svc := range serviceLst { - entry := tokens3.CatalogEntry{ - Type: svc.Type, - Name: svc.Name, - ID: svc.ID, - } - entries = append(entries, entry) - } - - return true, nil - }) - - if serviceListErr != nil { - return serviceListErr - } - - endpointListErr := endpoints.List(v3Client, endpoints.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - endpointList, err := endpoints.ExtractEndpoints(page) - if err != nil { - return false, err - } - - for _, endpoint := range endpointList { - entry := getEntryByServiceId(entries, endpoint.ServiceID) - - if entry != nil { - entry.Endpoints = append(entry.Endpoints, tokens3.Endpoint{ - URL: strings.Replace(endpoint.URL, "$(tenant_id)s", options.ProjectID, -1), - Region: endpoint.Region, - Interface: string(endpoint.Availability), - ID: endpoint.ID, - }) - } - } - - client.EndpointLocator = func(opts huaweicloudsdk.EndpointOpts) (string, error) { - return GetEndpointURLForAKSKAuth(&tokens3.ServiceCatalog{ - Entries: entries, - }, opts, options) - } - - return true, nil - }) - - if endpointListErr != nil { - return endpointListErr - } - - if client.EndpointLocator == nil { - return huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CENoEndPointInCatalogCode, huaweicloudsdk.CENoEndPointInCatalogMessage) - } - return nil - -} - -// AuthenticateV2 explicitly authenticates against the identity v2 endpoint. -func AuthenticateV2(client *huaweicloudsdk.ProviderClient, options tokenAuth.TokenOptions, eo huaweicloudsdk.EndpointOpts) error { - return tokenAuthV2(client, "", options, eo) -} - -func tokenAuthV2(client *huaweicloudsdk.ProviderClient, endpoint string, options tokenAuth.TokenOptions, eo huaweicloudsdk.EndpointOpts) error { - v2Client, err := NewIdentityV2(client, eo) - if err != nil { - return err - } - - if endpoint != "" { - v2Client.Endpoint = endpoint - } - - v2Opts := tokens2.AuthOptions{ - IdentityEndpoint: options.IdentityEndpoint, - Username: options.Username, - Password: options.Password, - TenantID: options.TenantID, - TenantName: options.TenantName, - AllowReauth: options.AllowReauth, - TokenID: options.TokenID, - } - - result := tokens2.Create(v2Client, v2Opts) - - token, err := result.ExtractToken() - if err != nil { - return err - } - - catalog, err := result.ExtractServiceCatalog() - if err != nil { - return err - } - - if options.AllowReauth { - // here we're creating a throw-away client (tac). it's a copy of the user's provider client, but - // with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`, - // this should retry authentication only once - tac := *client - tac.ReauthFunc = nil - tac.TokenID = "" - tao := options - tao.AllowReauth = false - client.ReauthFunc = func() error { - err := tokenAuthV2(&tac, endpoint, tao, eo) - if err != nil { - return err - } - client.TokenID = tac.TokenID - return nil - } - } - client.TokenID = token.ID - client.EndpointLocator = func(opts huaweicloudsdk.EndpointOpts) (string, error) { - return V2EndpointURL(catalog, opts) - } - - return nil -} - -// AuthenticateV3 explicitly authenticates against the identity v3 service. -func AuthenticateV3(client *huaweicloudsdk.ProviderClient, options tokens3.AuthOptionsBuilder, eo huaweicloudsdk.EndpointOpts) error { - return tokenAuthV3(client, "", options, eo) -} - -func tokenAuthV3(client *huaweicloudsdk.ProviderClient, endpoint string, opts tokens3.AuthOptionsBuilder, eo huaweicloudsdk.EndpointOpts) error { - // Override the generated service endpoint with the one returned by the version endpoint. - v3Client, err := NewIdentityV3(client, eo) - if err != nil { - return err - } - - if endpoint != "" { - v3Client.Endpoint = endpoint - } - - result := tokens3.Create(v3Client, opts) - - token, err := result.ExtractToken() - if err != nil { - return err - } - - catalog, err := result.ExtractServiceCatalog() - if err != nil { - return err - } - - client.TokenID = token.ID - - if opts.CanReauth() { - // here we're creating a throw-away client (tac). it's a copy of the user's provider client, but - // with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`, - // this should retry authentication only once - tac := *client - tac.ReauthFunc = nil - tac.TokenID = "" - var tao tokens3.AuthOptionsBuilder - switch ot := opts.(type) { - case *tokenAuth.TokenOptions: - o := *ot - o.AllowReauth = false - tao = &o - case *tokens3.TokenOptions: - o := *ot - o.AllowReauth = false - tao = &o - default: - tao = opts - } - client.ReauthFunc = func() error { - err := tokenAuthV3(&tac, endpoint, tao, eo) - if err != nil { - return err - } - client.TokenID = tac.TokenID - return nil - } - } - client.EndpointLocator = func(endpointOpts huaweicloudsdk.EndpointOpts) (string, error) { - return V3ExtractEndpointURL(catalog, endpointOpts, opts) - } - - return nil -} - -// NewIdentityV2 creates a ServiceClient that may be used to interact with the -// v2 identity service. -func NewIdentityV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - endpoint := client.IdentityBase + "v2.0/" - clientType := "identity" - var err error - if !reflect.DeepEqual(eo, huaweicloudsdk.EndpointOpts{}) { - eo.ApplyDefaults(clientType) - endpoint, err = client.EndpointLocator(eo) - if err != nil { - return nil, err - } - } - - return &huaweicloudsdk.ServiceClient{ - ProviderClient: client, - Endpoint: endpoint, - Type: clientType, - }, nil -} - -// NewIdentityV3 creates a ServiceClient that may be used to access the v3 -// identity service. -func NewIdentityV3(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - endpoint := client.IdentityBase + "v3/" - clientType := "identity" - var err error - if !reflect.DeepEqual(eo, huaweicloudsdk.EndpointOpts{}) { - eo.ApplyDefaults(clientType) - endpoint, err = client.EndpointLocator(eo) - if err != nil { - return nil, err - } - } - - // Ensure endpoint still has a suffix of v3. - // This is because EndpointLocator might have found a versionless - // endpoint and requests will fail unless targeted at /v3. - if !strings.HasSuffix(endpoint, "v3/") { - endpoint = endpoint + "v3/" - } - - return &huaweicloudsdk.ServiceClient{ - ProviderClient: client, - Endpoint: endpoint, - Type: clientType, - }, nil -} - -func initClientOpts(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts, clientType string) (*huaweicloudsdk.ServiceClient, error) { - sc := new(huaweicloudsdk.ServiceClient) - eo.ApplyDefaults(clientType) - url, err := client.EndpointLocator(eo) - if err != nil { - return sc, err - } - sc.ProviderClient = client - sc.Endpoint = url - sc.Type = clientType - return sc, nil -} - -// NewObjectStorageV1 creates a ServiceClient that may be used with the v1 -// object storage package. -func NewObjectStorageV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "object-store") -} - -// NewComputeV2 creates a ServiceClient that may be used with the v2 compute -// package. -func NewComputeV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "compute") -} - -// NewNetworkV2 creates a ServiceClient that may be used with the v2 network -// package. -func NewNetworkV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "network") - sc.ResourceBase = sc.Endpoint + "v2.0/" - return sc, err -} - -// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 -// block storage service. -func NewBlockStorageV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "volume") -} - -// NewBlockStorageV2 creates a ServiceClient that may be used to access the v2 -// block storage service. -func NewBlockStorageV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "volumev2") -} - -// NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service. -func NewBlockStorageV3(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "volumev3") -} - -// NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service. -func NewSharedFileSystemV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "sharev2") -} - -// NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1 -// CDN service. -func NewCDNV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "cdn") -} - -// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 -// orchestration service. -func NewOrchestrationV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "orchestration") -} - -// NewDBV1 creates a ServiceClient that may be used to access the v1 DB service. -func NewDBV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "database") -} - -// NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS -// service. -func NewDNSV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "dns") - sc.ResourceBase = sc.Endpoint + "v2/" - return sc, err -} - -// NewImageServiceV2 creates a ServiceClient that may be used to access the v2 -// image service. -func NewImageServiceV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "image") - sc.ResourceBase = sc.Endpoint + "v2/" - return sc, err -} - -// NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2 -// load balancer service. -func NewLoadBalancerV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "load-balancer") - sc.ResourceBase = sc.Endpoint + "v2.0/" - return sc, err -} - -// NewECSV1 creates a ServiceClient that may be used to access the v1 -// ecs service. -func NewECSV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "ecs") -} - -// NewECSV1_1 creates a ServiceClient that may be used to access the v1.1 -// ecs service. -func NewECSV1_1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "ecsv1.1") -} - -// NewECSV2 creates a ServiceClient that may be used to access the v2 -// ecs service. -func NewECSV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - return initClientOpts(client, eo, "ecsv2") -} - -// NewIMSV1 ... -func NewIMSV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "image") - sc.ResourceBase = sc.Endpoint + "v1/" - return sc, err -} - -// NewIMSV2 creates a ServiceClient that may be used to access the v2 -// image service. -func NewIMSV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "image") - sc.ResourceBase = sc.Endpoint + "v2/" - return sc, err -} - -// NewBSSV1 creates a ServiceClient that may be used to access the v1.0 -// BSS service. -func NewBSSV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "bssv1") - return sc, err -} - -// NewBSSIntlV1 creates a ServiceClient that may be used to access the v1.0 -// BSS-INTLV1 service. -func NewBSSIntlV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "bss-intlv1") - return sc, err -} - -// NewVPCV1 creates a ServiceClient that may be used with the v1 network -// package. -func NewVPCV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "vpc") - return sc, err -} - -// NewCESV1 creates a ServiceClient that may be used with the v1 cloud eye service -// package. -func NewCESV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - type details struct { - Details string `json:"details"` - Code string `json:"code"` - } - type CESError struct { - Message string `json:"message"` - Code int `json:"code"` - Details details `json:"details"` - Element string `json:"element"` - } - - sc, err := initClientOpts(client, eo, "cesv1") - sc.HandleError = func(httpStatus int, responseContent string) error { - var cesErr CESError - var code string - message := responseContent - marshalErr := json.Unmarshal([]byte(responseContent), &cesErr) - - if marshalErr == nil && cesErr.Details.Code != "" { - code = cesErr.Details.Code - message = cesErr.Details.Details - } else { - code = huaweicloudsdk.MatchErrorCode(httpStatus, message) - } - return &huaweicloudsdk.UnifiedError{ - ErrCode: code, - ErrMessage: message, - } - - } - return sc, err -} - -// NewVPCV2 creates a ServiceClient that may be used with the v2.0 vpc -// package. -func NewVPCV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "vpcv2.0") - return sc, err -} - -// NewASV1 creates a ServiceClient that may be used with the v1 as -// package. -func NewASV1(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "asv1") - return sc, err -} - -// NewASV2 creates a ServiceClient that may be used with the v2 as -// package. -func NewASV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "asv2") - return sc, err -} - -// NewFGSV2 creates a ServiceClient that may be used with the v2 as -// package. -func NewFGSV2(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "fgsv2") - return sc, err -} - -// NewRDSV3 creates a ServiceClient that may be used with the v3 rds -// package. -func NewRDSV3(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "rdsv3") - return sc, err -} - -// NewCCEV3 creates a ServiceClient that may be used with the v3 CCE -// package. -func NewCCEV3(client *huaweicloudsdk.ProviderClient, eo huaweicloudsdk.EndpointOpts) (*huaweicloudsdk.ServiceClient, error) { - sc, err := initClientOpts(client, eo, "ccev3") - return sc, err -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/endpoint_location.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/endpoint_location.go deleted file mode 100644 index dd3ed0bd6f15..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/endpoint_location.go +++ /dev/null @@ -1,297 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 openstack - -import ( - "fmt" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk" - tokenAuth "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token" - tokens2 "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens" - tokens3 "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens" - - "errors" - "os" - "strings" -) - -// service have same endpoint address in different location -var endpointSchemaList = map[string]string{ - "COMPUTE": "https://ecs.%(region)s.%(domain)s/v2/%(projectID)s/", - "ECSV1.1": "https://ecs.%(region)s.%(domain)s/v1.1/%(projectID)s/", - "ECSV2": "https://ecs.%(region)s.%(domain)s/v2/%(projectID)s/", - "ECS": "https://ecs.%(region)s.%(domain)s/v1/%(projectID)s/", - "IMAGE": "https://ims.%(region)s.%(domain)s/", - "NETWORK": "https://vpc.%(region)s.%(domain)s/", - "VOLUMEV2": "https://evs.%(region)s.%(domain)s/v2/%(projectID)s/", - //"ANTIDDOS": "https://antiddos.%(region)s.%(domain)s/", - //"BSS": "https://bss.%(region)s.%(domain)s/", - "BSSV1": "https://bss.%(domain)s/v1.0/", - "BSSINTLV1": "https://bss.%(domain)s/v1.0/", - "VPC": "https://vpc.%(region)s.%(domain)s/v1/%(projectID)s/", - "CESV1": "https://ces.%(region)s.%(domain)s/V1.0/%(projectID)s/", - "VPCV2.0": "https://vpc.%(region)s.%(domain)s/v2.0/%(projectID)s/", - "ASV1": "https://as.%(region)s.%(domain)s/autoscaling-api/v1/%(projectID)s/", - "ASV2": "https://as.%(region)s.%(domain)s/autoscaling-api/v2/%(projectID)s/", - "DNS": "https://dns.%(region)s.%(domain)s/", - "FGSV2": "https://functiongraph.%(region)s.%(domain)s/v2/%(projectID)s/", - "RDSV3": "https://rds.%(region)s.%(domain)s/v3/%(projectID)s/", - "IDENTITY": "https://iam.%(domain)s/v3", - /* - Sample Call to retrieve cluster info: https://cce.cn-north-1.myhuaweicloud.com/api/v3/projects/017a290a8242480e82de8db804c1718d/clusters/19d4f935-4c45-11ea-b2e7-0255ac101eee - Huawei Cloud API Doc: https://support.huaweicloud.com/api-cce/cce_02_0237.html - https://{cce_endpoint}/api/v3/projects/{project_id}/clusters/{cluster_id} - */ - "CCEV3": "https://cce.%(region)s.%(domain)s/api/v3/projects/%(projectID)s/", -} - -/* -V2EndpointURL discovers the endpoint URL for a specific service from a -ServiceCatalog acquired during the v2 identity service. - -The specified EndpointOpts are used to identify a unique, unambiguous endpoint -to return. It's an error both when multiple endpoints match the provided -criteria and when none do. The minimum that can be specified is a Type, but you -will also often need to specify a Name and/or a Region depending on what's -available on your OpenStack deployment. -*/ -func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts huaweicloudsdk.EndpointOpts) (string, error) { - // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. - var endpoints = make([]tokens2.Endpoint, 0, 1) - for _, entry := range catalog.Entries { - if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { - for _, endpoint := range entry.Endpoints { - if opts.Region == "" || endpoint.Region == opts.Region { - endpoints = append(endpoints, endpoint) - } - } - } - } - - // Report an error if the options were ambiguous. - if len(endpoints) > 1 { - // err := &ErrMultipleMatchingEndpointsV2{} - // err.Endpoints = endpoints - // return "", err - - message := fmt.Sprintf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints) - err := huaweicloudsdk.NewSystemCommonError("Com.2000", message) - return "", err - } - - // Extract the appropriate URL from the matching Endpoint. - for _, endpoint := range endpoints { - switch opts.Availability { - case huaweicloudsdk.AvailabilityPublic: - return huaweicloudsdk.NormalizeURL(endpoint.PublicURL), nil - case huaweicloudsdk.AvailabilityInternal: - return huaweicloudsdk.NormalizeURL(endpoint.InternalURL), nil - case huaweicloudsdk.AvailabilityAdmin: - return huaweicloudsdk.NormalizeURL(endpoint.AdminURL), nil - default: - // err := &ErrInvalidAvailabilityProvided{} - // err.Argument = "Availability" - // err.Value = opts.Availability - // return "", err - - value := fmt.Sprintf("Availability:%+v", opts.Availability) - message := fmt.Sprintf(huaweicloudsdk.CEInvalidInputMessage, value) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEInvalidInputCode, message) - return "", err - } - } - - // Report an error if there were no matching endpoints. - // err := &gophercloud.ErrEndpointNotFound{} - // return "", err - - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CENoEndPointInCatalogCode, huaweicloudsdk.CENoEndPointInCatalogMessage) - return "", err -} - -// V3ExtractEndpointURL Extract Endpoints from the catalog entries that match the requested Type, Interface, Name if provided, and Region if provided. -func V3ExtractEndpointURL(catalog *tokens3.ServiceCatalog, opts huaweicloudsdk.EndpointOpts, tokenOptions tokens3.AuthOptionsBuilder) (string, error) { - - if opts.Type == "" { - return "", errors.New("Service type can not be empty.") - } - - ss := strings.Replace(opts.Type, "-", "_", -1) - key := fmt.Sprintf("SDK_%s_ENDPOINT_OVERRIDE", strings.ToUpper(ss)) - endpointFromEnv := os.Getenv(key) - if endpointFromEnv != "" { - if opts, ok := tokenOptions.(*tokenAuth.TokenOptions); ok { - endpointFromEnv = strings.Replace(endpointFromEnv, "%(projectID)s", opts.ProjectID, 1) - return endpointFromEnv, nil - } - } - - return V3EndpointURL(catalog, opts) -} - -// V3TokenIdExtractEndpointURL Extract Endpoints from the catalog entries that match the requested Type, Interface, Name if provided, and Region if provided. -func V3TokenIdExtractEndpointURL(catalog *tokens3.ServiceCatalog, opts huaweicloudsdk.EndpointOpts, tokenIdOptions tokenAuth.TokenIdOptions) (string, error) { - - if opts.Type == "" { - return "", errors.New("Service type can not be empty.") - } - - ss := strings.Replace(opts.Type, "-", "_", -1) - key := fmt.Sprintf("SDK_%s_ENDPOINT_OVERRIDE", strings.ToUpper(ss)) - endpointFromEnv := os.Getenv(key) - if endpointFromEnv != "" { - endpointFromEnv = strings.Replace(endpointFromEnv, "%(projectID)s", tokenIdOptions.ProjectID, 1) - return endpointFromEnv, nil - } - - return V3EndpointURL(catalog, opts) -} - -/* -V3EndpointURL discovers the endpoint URL for a specific service from a Catalog -acquired during the v3 identity service. - -The specified EndpointOpts are used to identify a unique, unambiguous endpoint -to return. It's an error both when multiple endpoints match the provided -criteria and when none do. The minimum that can be specified is a Type, but you -will also often need to specify a Name and/or a Region depending on what's -available on your OpenStack deployment. -*/ -func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts huaweicloudsdk.EndpointOpts) (string, error) { - var endpoints = make([]tokens3.Endpoint, 0, 1) - for _, entry := range catalog.Entries { - if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { - for _, endpoint := range entry.Endpoints { - if opts.Availability != huaweicloudsdk.AvailabilityAdmin && - opts.Availability != huaweicloudsdk.AvailabilityPublic && - opts.Availability != huaweicloudsdk.AvailabilityInternal { - // err := &ErrInvalidAvailabilityProvided{} - // err.Argument = "Availability" - // err.Value = opts.Availability - // return "", err - - value := fmt.Sprintf("Availability:%+v", opts.Availability) - message := fmt.Sprintf(huaweicloudsdk.CEInvalidInputMessage, value) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEInvalidInputCode, message) - return "", err - } - if (opts.Availability == huaweicloudsdk.Availability(endpoint.Interface)) && - (opts.Region == "" || endpoint.Region == opts.Region) { - endpoints = append(endpoints, endpoint) - } - } - } - } - - // Report an error if the options were ambiguous. - if len(endpoints) > 1 { - //return "", ErrMultipleMatchingEndpointsV3{Endpoints: endpoints} - - message := fmt.Sprintf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints) - err := huaweicloudsdk.NewSystemCommonError("Com.2000", message) - return "", err - } - - // Extract the URL from the matching Endpoint. - for _, endpoint := range endpoints { - return huaweicloudsdk.NormalizeURL(endpoint.URL), nil - } - - // Report an error if there were no matching endpoints. - // err := &gophercloud.ErrEndpointNotFound{} - // return "", err - - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CENoEndPointInCatalogCode, huaweicloudsdk.CENoEndPointInCatalogMessage) - return "", err -} - -// GetEndpointURLForAKSKAuth discovers the endpoint from V3EndpointURL function firstly, -// if the endpoint is null then concat the service type and domain as the endpoint -func GetEndpointURLForAKSKAuth(catalog *tokens3.ServiceCatalog, opts huaweicloudsdk.EndpointOpts, akskOptions aksk.AKSKOptions) (string, error) { - - if akskOptions.Cloud != "" { - akskOptions.Domain = akskOptions.Cloud - } - - if opts.Type == "" { - return "", errors.New("Service type can not be empty.") - } - - ss := strings.Replace(opts.Type, "-", "_", -1) - key := fmt.Sprintf("SDK_%s_ENDPOINT_OVERRIDE", strings.ToUpper(ss)) - endpointFromEnv := os.Getenv(key) - if endpointFromEnv != "" { - //endpointFromEnv = strings.Replace(endpointFromEnv, "%(region)s", akskOptions.Region, 1) - //endpointFromEnv = strings.Replace(endpointFromEnv, "%(domain)s", akskOptions.Domain, 1) - endpointFromEnv = strings.Replace(endpointFromEnv, "%(projectID)s", akskOptions.ProjectID, 1) - return endpointFromEnv, nil - } - - endpoint, err := V3EndpointURL(catalog, opts) - if err != nil || endpoint == "" { - if akskOptions.Domain == "" { - return "", errors.New("AKSKOptions.Cloud can not be empty.") - } - - region := opts.Region - - if region == "" { - region = akskOptions.Region - } - - if endpointSchema, ok := endpointSchemaList[strings.ToUpper(opts.Type)]; ok { - endpoint = strings.Replace(endpointSchema, "%(domain)s", akskOptions.Domain, 1) - endpoint = strings.Replace(endpoint, "%(region)s", region, 1) - endpoint = strings.Replace(endpoint, "%(projectID)s", akskOptions.ProjectID, 1) - - return endpoint, nil - } - } - - return endpoint, err -} - -/* - GetEndpointURLForAKSKAuth discovers the endpoint from V3EndpointURL function firstly, - if the endpoint is null then concat the service type and domain as the endpoint -*/ -/* -func GetEndpointURLForAKSKAuth(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts, akskOptions aksk.AKSKOptions) (string, error) { - if opts.Region == "" { - opts.Region = akskOptions.Region - } - - endpoint, err := V3EndpointURL(catalog, opts) - //fmt.Println("EDP0", endpoint) - if err != nil || endpoint == "" { - if akskOptions.Domain == "" { - return "", errors.New("ServiceDomainName can not be empty.") - } - //fmt.Println("EDP1", endpoint) - if endpointSchema, ok := endpointSchemaList[strings.ToUpper(opts.Type)]; ok { - endpoint = strings.Replace(endpointSchema, "%(domain)s", akskOptions.Domain, 1) - endpoint = strings.Replace(endpoint, "%(region)s", opts.Region, 1) - endpoint = strings.Replace(endpoint, "%(projectID)s", akskOptions.ProjectID, 1) - //fmt.Println("EDP2", endpoint) - return endpoint, nil - } - } - - return endpoint, err -} -*/ diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tenants/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tenants/results.go deleted file mode 100644 index 771ec2e378aa..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tenants/results.go +++ /dev/null @@ -1,107 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tenants - -import ( - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination" -) - -// Tenant is a grouping of users in the identity service. -type Tenant struct { - // ID is a unique identifier for this tenant. - ID string `json:"id"` - - // Name is a friendlier user-facing name for this tenant. - Name string `json:"name"` - - // Description is a human-readable explanation of this Tenant's purpose. - Description string `json:"description"` - - // Enabled indicates whether or not a tenant is active. - Enabled bool `json:"enabled"` -} - -// TenantPage is a single page of Tenant results. -type TenantPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Tenants contains any results. -func (r TenantPage) IsEmpty() (bool, error) { - tenants, err := ExtractTenants(r) - return len(tenants) == 0, err -} - -// NextPageURL extracts the "next" link from the tenants_links section of the result. -func (r TenantPage) NextPageURL() (string, error) { - var s struct { - Links []huaweicloudsdk.Link `json:"tenants_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return huaweicloudsdk.ExtractNextURL(s.Links) -} - -// ExtractTenants returns a slice of Tenants contained in a single page of -// results. -func ExtractTenants(r pagination.Page) ([]Tenant, error) { - var s struct { - Tenants []Tenant `json:"tenants"` - } - err := (r.(TenantPage)).ExtractInto(&s) - return s.Tenants, err -} - -type tenantResult struct { - huaweicloudsdk.Result -} - -// Extract interprets any tenantResults as a Tenant. -func (r tenantResult) Extract() (*Tenant, error) { - var s struct { - Tenant *Tenant `json:"tenant"` - } - err := r.ExtractInto(&s) - return s.Tenant, err -} - -// GetResult is the response from a Get request. Call its Extract method to -// interpret it as a Tenant. -type GetResult struct { - tenantResult -} - -// CreateResult is the response from a Create request. Call its Extract method -// to interpret it as a Tenant. -type CreateResult struct { - tenantResult -} - -// DeleteResult is the response from a Get request. Call its ExtractErr method -// to determine if the call succeeded or failed. -type DeleteResult struct { - huaweicloudsdk.ErrResult -} - -// UpdateResult is the response from a Update request. Call its Extract method -// to interpret it as a Tenant. -type UpdateResult struct { - tenantResult -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/requests.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/requests.go deleted file mode 100644 index 442db342038a..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/requests.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tokens - -import "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - -// PasswordCredentialsV2 represents the required options to authenticate -// with a username and password. -type PasswordCredentialsV2 struct { - Username string `json:"username" required:"true"` - Password string `json:"password" required:"true"` -} - -// TokenCredentialsV2 represents the required options to authenticate -// with a token. -type TokenCredentialsV2 struct { - ID string `json:"id,omitempty" required:"true"` -} - -// AuthOptionsV2 wraps a gophercloud AuthOptions in order to adhere to the -// AuthOptionsBuilder interface. -type AuthOptionsV2 struct { - PasswordCredentials *PasswordCredentialsV2 `json:"passwordCredentials,omitempty" xor:"TokenCredentials"` - - // The TenantID and TenantName fields are optional for the Identity V2 API. - // Some providers allow you to specify a TenantName instead of the TenantId. - // Some require both. Your provider's authentication policies will determine - // how these fields influence authentication. - TenantID string `json:"tenantId,omitempty"` - TenantName string `json:"tenantName,omitempty"` - - // TokenCredentials allows users to authenticate (possibly as another user) - // with an authentication token ID. - TokenCredentials *TokenCredentialsV2 `json:"token,omitempty" xor:"PasswordCredentials"` -} - -// AuthOptionsBuilder allows extensions to add additional parameters to the -// token create request. -type AuthOptionsBuilder interface { - // ToTokenCreateMap assembles the Create request body, returning an error - // if parameters are missing or inconsistent. - ToTokenV2CreateMap() (map[string]interface{}, error) -} - -// AuthOptions are the valid options for Openstack Identity v2 authentication. -// For field descriptions, see gophercloud.AuthOptions. -type AuthOptions struct { - IdentityEndpoint string `json:"-"` - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - TenantID string `json:"tenantId,omitempty"` - TenantName string `json:"tenantName,omitempty"` - AllowReauth bool `json:"-"` - TokenID string -} - -// ToTokenV2CreateMap builds a token request body from the given AuthOptions. -func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) { - v2Opts := AuthOptionsV2{ - TenantID: opts.TenantID, - TenantName: opts.TenantName, - } - - if opts.Password != "" { - v2Opts.PasswordCredentials = &PasswordCredentialsV2{ - Username: opts.Username, - Password: opts.Password, - } - } else { - v2Opts.TokenCredentials = &TokenCredentialsV2{ - ID: opts.TokenID, - } - } - - b, err := huaweicloudsdk.BuildRequestBody(v2Opts, "auth") - if err != nil { - return nil, err - } - return b, nil -} - -// Create authenticates to the identity service and attempts to acquire a Token. -// Generally, rather than interact with this call directly, end users should -// call openstack.AuthenticatedClient(), which abstracts all of the gory details -// about navigating service catalogs and such. -func Create(client *huaweicloudsdk.ServiceClient, auth AuthOptionsBuilder) (r CreateResult) { - b, err := auth.ToTokenV2CreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(CreateURL(client), b, &r.Body, &huaweicloudsdk.RequestOpts{ - OkCodes: []int{200, 203}, - MoreHeaders: map[string]string{"X-Auth-Token": ""}, - }) - return -} - -// Get validates and retrieves information for user's token. -func Get(client *huaweicloudsdk.ServiceClient, token string) (r GetResult) { - _, r.Err = client.Get(GetURL(client, token), &r.Body, &huaweicloudsdk.RequestOpts{ - OkCodes: []int{200, 203}, - }) - return -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/results.go deleted file mode 100644 index cf79dfde85fe..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/results.go +++ /dev/null @@ -1,190 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tokens - -import ( - "time" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tenants" -) - -// Token provides only the most basic information related to an authentication -// token. -type Token struct { - // ID provides the primary means of identifying a user to the OpenStack API. - // OpenStack defines this field as an opaque value, so do not depend on its - // content. It is safe, however, to compare for equality. - ID string - - // ExpiresAt provides a timestamp in ISO 8601 format, indicating when the - // authentication token becomes invalid. After this point in time, future - // API requests made using this authentication token will respond with - // errors. Either the caller will need to reauthenticate manually, or more - // preferably, the caller should exploit automatic re-authentication. - // See the AuthOptions structure for more details. - ExpiresAt time.Time - - // Tenant provides information about the tenant to which this token grants - // access. - Tenant tenants.Tenant -} - -// Role is a role for a user. -type Role struct { - Name string `json:"name"` -} - -// User is an OpenStack user. -type User struct { - ID string `json:"id"` - Name string `json:"name"` - UserName string `json:"username"` - Roles []Role `json:"roles"` -} - -// Endpoint represents a single API endpoint offered by a service. -// It provides the public and internal URLs, if supported, along with a region -// specifier, again if provided. -// -// The significance of the Region field will depend upon your provider. -// -// In addition, the interface offered by the service will have version -// information associated with it through the VersionId, VersionInfo, and -// VersionList fields, if provided or supported. -// -// In all cases, fields which aren't supported by the provider and service -// combined will assume a zero-value (""). -type Endpoint struct { - TenantID string `json:"tenantId"` - PublicURL string `json:"publicURL"` - InternalURL string `json:"internalURL"` - AdminURL string `json:"adminURL"` - Region string `json:"region"` - VersionID string `json:"versionId"` - VersionInfo string `json:"versionInfo"` - VersionList string `json:"versionList"` -} - -// CatalogEntry provides a type-safe interface to an Identity API V2 service -// catalog listing. -// -// Each class of service, such as cloud DNS or block storage services, will have -// a single CatalogEntry representing it. -// -// Note: when looking for the desired service, try, whenever possible, to key -// off the type field. Otherwise, you'll tie the representation of the service -// to a specific provider. -type CatalogEntry struct { - // Name will contain the provider-specified name for the service. - Name string `json:"name"` - - // Type will contain a type string if OpenStack defines a type for the - // service. Otherwise, for provider-specific services, the provider may assign - // their own type strings. - Type string `json:"type"` - - // Endpoints will let the caller iterate over all the different endpoints that - // may exist for the service. - Endpoints []Endpoint `json:"endpoints"` -} - -// ServiceCatalog provides a view into the service catalog from a previous, -// successful authentication. -type ServiceCatalog struct { - Entries []CatalogEntry -} - -// CreateResult is the response from a Create request. Use ExtractToken() to -// interpret it as a Token, or ExtractServiceCatalog() to interpret it as a -// service catalog. -type CreateResult struct { - huaweicloudsdk.Result -} - -// GetResult is the deferred response from a Get call, which is the same with a -// Created token. Use ExtractUser() to interpret it as a User. -type GetResult struct { - CreateResult -} - -// ExtractToken returns the just-created Token from a CreateResult. -func (r CreateResult) ExtractToken() (*Token, error) { - var s struct { - Access struct { - Token struct { - Expires string `json:"expires"` - ID string `json:"id"` - Tenant tenants.Tenant `json:"tenant"` - } `json:"token"` - } `json:"access"` - } - - err := r.ExtractInto(&s) - if err != nil { - return nil, err - } - - expiresTs, err := time.Parse(huaweicloudsdk.RFC3339Milli, s.Access.Token.Expires) - if err != nil { - return nil, err - } - - return &Token{ - ID: s.Access.Token.ID, - ExpiresAt: expiresTs, - Tenant: s.Access.Token.Tenant, - }, nil -} - -// ExtractTokenID implements the gophercloud.AuthResult interface. The returned -// string is the same as the ID field of the Token struct returned from -// ExtractToken(). -func (r CreateResult) ExtractTokenID() (string, error) { - var s struct { - Access struct { - Token struct { - ID string `json:"id"` - } `json:"token"` - } `json:"access"` - } - err := r.ExtractInto(&s) - return s.Access.Token.ID, err -} - -// ExtractServiceCatalog returns the ServiceCatalog that was generated along -// with the user's Token. -func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) { - var s struct { - Access struct { - Entries []CatalogEntry `json:"serviceCatalog"` - } `json:"access"` - } - err := r.ExtractInto(&s) - return &ServiceCatalog{Entries: s.Access.Entries}, err -} - -// ExtractUser returns the User from a GetResult. -func (r GetResult) ExtractUser() (*User, error) { - var s struct { - Access struct { - User User `json:"user"` - } `json:"access"` - } - err := r.ExtractInto(&s) - return &s.Access.User, err -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/urls.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/urls.go deleted file mode 100644 index 61f66ff4a398..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v2/tokens/urls.go +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tokens - -import "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - -// CreateURL generates the URL used to create new Tokens. -func CreateURL(client *huaweicloudsdk.ServiceClient) string { - return client.ServiceURL("tokens") -} - -// GetURL generates the URL used to Validate Tokens. -func GetURL(client *huaweicloudsdk.ServiceClient, token string) string { - return client.ServiceURL("tokens", token) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/requests.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/requests.go deleted file mode 100644 index 89a51d91ae62..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/requests.go +++ /dev/null @@ -1,156 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 endpoints - -import ( - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination" -) - -// CreateOptsBuilder ... -type CreateOptsBuilder interface { - ToEndpointCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains the subset of Endpoint attributes that should be used -// to create an Endpoint. -type CreateOpts struct { - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the gophercloud.Availability type. - Availability huaweicloudsdk.Availability `json:"interface" required:"true"` - - // Name is the name of the Endpoint. - Name string `json:"name" required:"true"` - - // Region is the region the Endpoint is located in. - // This field can be omitted or left as a blank string. - Region string `json:"region,omitempty"` - - // URL is the url of the Endpoint. - URL string `json:"url" required:"true"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `json:"service_id" required:"true"` -} - -// ToEndpointCreateMap builds a request body from the Endpoint Create options. -func (opts CreateOpts) ToEndpointCreateMap() (map[string]interface{}, error) { - return huaweicloudsdk.BuildRequestBody(opts, "endpoint") -} - -// Create inserts a new Endpoint into the service catalog. -func Create(client *huaweicloudsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToEndpointCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(listURL(client), &b, &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add parameters to the List request. -type ListOptsBuilder interface { - ToEndpointListParams() (string, error) -} - -// ListOpts allows finer control over the endpoints returned by a List call. -// All fields are optional. -type ListOpts struct { - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the gophercloud.Availability type. - Availability huaweicloudsdk.Availability `q:"interface"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `q:"service_id"` - - // Page is a result page to reference in the results. - Page int `q:"page"` - - // PerPage determines how many results per page are returned. - PerPage int `q:"per_page"` -} - -// ToEndpointListParams builds a list request from the List options. -func (opts ListOpts) ToEndpointListParams() (string, error) { - q, err := huaweicloudsdk.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates endpoints in a paginated collection, optionally filtered -// by ListOpts criteria. -func List(client *huaweicloudsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { - u := listURL(client) - if opts != nil { - q, err := huaweicloudsdk.BuildQueryString(opts) - if err != nil { - return pagination.Pager{Err: err} - } - u += q.String() - } - return pagination.NewPager(client, u, func(r pagination.PageResult) pagination.Page { - return EndpointPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// UpdateOptsBuilder allows extensions to add parameters to the Update request. -type UpdateOptsBuilder interface { - ToEndpointUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contains the subset of Endpoint attributes that should be used to -// update an Endpoint. -type UpdateOpts struct { - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the gophercloud.Availability type. - Availability huaweicloudsdk.Availability `json:"interface,omitempty"` - - // Name is the name of the Endpoint. - Name string `json:"name,omitempty"` - - // Region is the region the Endpoint is located in. - // This field can be omitted or left as a blank string. - Region string `json:"region,omitempty"` - - // URL is the url of the Endpoint. - URL string `json:"url,omitempty"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `json:"service_id,omitempty"` -} - -// ToEndpointUpdateMap builds an update request body from the Update options. -func (opts UpdateOpts) ToEndpointUpdateMap() (map[string]interface{}, error) { - return huaweicloudsdk.BuildRequestBody(opts, "endpoint") -} - -// Update changes an existing endpoint with new data. -func Update(client *huaweicloudsdk.ServiceClient, endpointID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToEndpointUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(endpointURL(client, endpointID), &b, &r.Body, nil) - return -} - -// Delete removes an endpoint from the service catalog. -func Delete(client *huaweicloudsdk.ServiceClient, endpointID string) (r DeleteResult) { - _, r.Err = client.Delete(endpointURL(client, endpointID), nil) - return -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/results.go deleted file mode 100644 index 4bf57447ae27..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/results.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 endpoints - -import ( - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination" -) - -type commonResult struct { - huaweicloudsdk.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete -// Endpoint. An error is returned if the original call or the extraction failed. -func (r commonResult) Extract() (*Endpoint, error) { - var s struct { - Endpoint *Endpoint `json:"endpoint"` - } - err := r.ExtractInto(&s) - return s.Endpoint, err -} - -// CreateResult is the response from a Create operation. Call its Extract -// method to interpret it as an Endpoint. -type CreateResult struct { - commonResult -} - -// UpdateResult is the response from an Update operation. Call its Extract -// method to interpret it as an Endpoint. -type UpdateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - huaweicloudsdk.ErrResult -} - -// Endpoint describes the entry point for another service's API. -type Endpoint struct { - // ID is the unique ID of the endpoint. - ID string `json:"id"` - - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the gophercloud.Availability type. - Availability huaweicloudsdk.Availability `json:"interface"` - - // Name is the name of the Endpoint. - Name string `json:"name"` - - // Region is the region the Endpoint is located in. - Region string `json:"region"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `json:"service_id"` - - // URL is the url of the Endpoint. - URL string `json:"url"` -} - -// EndpointPage is a single page of Endpoint results. -type EndpointPage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if no Endpoints were returned. -func (r EndpointPage) IsEmpty() (bool, error) { - es, err := ExtractEndpoints(r) - return len(es) == 0, err -} - -// ExtractEndpoints extracts an Endpoint slice from a Page. -func ExtractEndpoints(r pagination.Page) ([]Endpoint, error) { - var s struct { - Endpoints []Endpoint `json:"endpoints"` - } - err := (r.(EndpointPage)).ExtractInto(&s) - return s.Endpoints, err -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/urls.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/urls.go deleted file mode 100644 index 8c428cf98f7b..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/endpoints/urls.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 endpoints - -import "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - -func listURL(client *huaweicloudsdk.ServiceClient) string { - return client.ServiceURL("endpoints") -} - -func endpointURL(client *huaweicloudsdk.ServiceClient, endpointID string) string { - return client.ServiceURL("endpoints", endpointID) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/requests.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/requests.go deleted file mode 100644 index 7b8aa578033b..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/requests.go +++ /dev/null @@ -1,170 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 services - -import ( - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination" -) - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToServiceCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a service. -type CreateOpts struct { - // Type is the type of the service. - Type string `json:"type"` - - // Enabled is whether or not the service is enabled. - Enabled *bool `json:"enabled,omitempty"` - - // Extra is free-form extra key/value pairs to describe the service. - Extra map[string]interface{} `json:"-"` -} - -// ToServiceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToServiceCreateMap() (map[string]interface{}, error) { - b, err := huaweicloudsdk.BuildRequestBody(opts, "service") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["service"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Create adds a new service of the requested type to the catalog. -func Create(client *huaweicloudsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToServiceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &huaweicloudsdk.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// ListOptsBuilder enables extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToServiceListMap() (string, error) -} - -// ListOpts provides options for filtering the List results. -type ListOpts struct { - // ServiceType filter the response by a type of service. - ServiceType string `q:"type"` - - // Name filters the response by a service name. - Name string `q:"name"` -} - -// ToServiceListMap builds a list query from the list options. -func (opts ListOpts) ToServiceListMap() (string, error) { - q, err := huaweicloudsdk.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the services available to a specific user. -func List(client *huaweicloudsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToServiceListMap() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ServicePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get returns additional information about a service, given its ID. -func Get(client *huaweicloudsdk.ServiceClient, serviceID string) (r GetResult) { - _, r.Err = client.Get(serviceURL(client, serviceID), &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToServiceUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts provides options for updating a service. -type UpdateOpts struct { - // Type is the type of the service. - Type string `json:"type"` - - // Enabled is whether or not the service is enabled. - Enabled *bool `json:"enabled,omitempty"` - - // Extra is free-form extra key/value pairs to describe the service. - Extra map[string]interface{} `json:"-"` -} - -// ToServiceUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToServiceUpdateMap() (map[string]interface{}, error) { - b, err := huaweicloudsdk.BuildRequestBody(opts, "service") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["service"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Update updates an existing Service. -func Update(client *huaweicloudsdk.ServiceClient, serviceID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToServiceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(updateURL(client, serviceID), &b, &r.Body, &huaweicloudsdk.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete removes an existing service. -// It either deletes all associated endpoints, or fails until all endpoints -// are deleted. -func Delete(client *huaweicloudsdk.ServiceClient, serviceID string) (r DeleteResult) { - _, r.Err = client.Delete(serviceURL(client, serviceID), nil) - return -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/results.go deleted file mode 100644 index 63d1aea295d6..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/results.go +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 services - -import ( - "encoding/json" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/internal" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination" -) - -type serviceResult struct { - huaweicloudsdk.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete -// Service. An error is returned if the original call or the extraction failed. -func (r serviceResult) Extract() (*Service, error) { - var s struct { - Service *Service `json:"service"` - } - err := r.ExtractInto(&s) - return s.Service, err -} - -// CreateResult is the response from a Create request. Call its Extract method -// to interpret it as a Service. -type CreateResult struct { - serviceResult -} - -// GetResult is the response from a Get request. Call its Extract method -// to interpret it as a Service. -type GetResult struct { - serviceResult -} - -// UpdateResult is the response from an Update request. Call its Extract method -// to interpret it as a Service. -type UpdateResult struct { - serviceResult -} - -// DeleteResult is the response from a Delete request. Call its ExtractErr -// method to interpret it as a Service. -type DeleteResult struct { - huaweicloudsdk.ErrResult -} - -// Service represents an OpenStack Service. -type Service struct { - // ID is the unique ID of the service. - ID string `json:"id"` - - // Type is the type of the service. - Name string `json:"name"` - - // Type is the type of the service. - Type string `json:"type"` - - // Enabled is whether or not the service is enabled. - Enabled bool `json:"enabled"` - - // Links contains referencing links to the service. - Links map[string]interface{} `json:"links"` - - // Extra is a collection of miscellaneous key/values. - Extra map[string]interface{} `json:"-"` -} - -// UnmarshalJSON ... -func (r *Service) UnmarshalJSON(b []byte) error { - type tmp Service - var s struct { - tmp - Extra map[string]interface{} `json:"extra"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Service(s.tmp) - - // Collect other fields and bundle them into Extra - // but only if a field titled "extra" wasn't sent. - if s.Extra != nil { - r.Extra = s.Extra - } else { - var result interface{} - err := json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - r.Extra = internal.RemainingKeys(Service{}, resultMap) - } - } - - return err -} - -// ServicePage is a single page of Service results. -type ServicePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if the ServicePage contains no results. -func (p ServicePage) IsEmpty() (bool, error) { - services, err := ExtractServices(p) - return len(services) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (p ServicePage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := p.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractServices extracts a slice of Services from a Collection acquired -// from List. -func ExtractServices(r pagination.Page) ([]Service, error) { - var s struct { - Services []Service `json:"services"` - } - err := (r.(ServicePage)).ExtractInto(&s) - return s.Services, err -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/urls.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/urls.go deleted file mode 100644 index e948df1447a5..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/services/urls.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 services - -import "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - -func listURL(client *huaweicloudsdk.ServiceClient) string { - return client.ServiceURL("services") -} - -func createURL(client *huaweicloudsdk.ServiceClient) string { - return client.ServiceURL("services") -} - -func serviceURL(client *huaweicloudsdk.ServiceClient, serviceID string) string { - return client.ServiceURL("services", serviceID) -} - -func updateURL(client *huaweicloudsdk.ServiceClient, serviceID string) string { - return client.ServiceURL("services", serviceID) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/requests.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/requests.go deleted file mode 100644 index daaf2fc815de..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/requests.go +++ /dev/null @@ -1,242 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tokens - -import ( - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/token" -) - -// Scope allows a created token to be limited to a specific domain or project. -type Scope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string -} - -// AuthOptionsBuilder provides the ability for extensions to add additional -// parameters to TokenOptions. Extensions must satisfy all required methods. -type AuthOptionsBuilder interface { - // ToTokenV3CreateMap assembles the Create request body, returning an error - // if parameters are missing or inconsistent. - ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) - ToTokenV3ScopeMap() (map[string]interface{}, error) - CanReauth() bool -} - -// TokenOptions represents options for authenticating a user. -type TokenOptions struct { - // IdentityEndpoint specifies the HTTP endpoint that is required to work with - // the Identity API of the appropriate version. While it's ultimately needed - // by all of the identity services, it will often be populated by a - // provider-level function. - IdentityEndpoint string `json:"-"` - - // Username is required if using Identity V2 API. Consult with your provider's - // control panel to discover your account's username. In Identity V3, either - // UserID or a combination of Username and DomainID or DomainName are needed. - Username string `json:"username,omitempty"` - UserID string `json:"id,omitempty"` - - Password string `json:"password,omitempty"` - - // At most one of DomainID and DomainName must be provided if using Username - // with Identity V3. Otherwise, either are optional. - DomainID string `json:"-"` - DomainName string `json:"name,omitempty"` - - // AllowReauth should be set to true if you grant permission for Gophercloud - // to cache your credentials in memory, and to allow Gophercloud to attempt - // to re-authenticate automatically if/when your token expires. If you set - // it to false, it will not cache these settings, but re-authentication will - // not be possible. This setting defaults to false. - AllowReauth bool `json:"-"` - - // TokenID allows users to authenticate (possibly as another user) with an - // authentication token ID. - TokenID string `json:"-"` - - Scope Scope `json:"-"` -} - -// ToTokenV3CreateMap builds a request body from TokenOptions. -func (opts *TokenOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { - gophercloudAuthOpts := token.TokenOptions{ - Username: opts.Username, - UserID: opts.UserID, - Password: opts.Password, - DomainID: opts.DomainID, - DomainName: opts.DomainName, - AllowReauth: opts.AllowReauth, - TokenID: opts.TokenID, - } - - return gophercloudAuthOpts.ToTokenV3CreateMap(scope) -} - -// ToTokenV3ScopeMap builds a scope request body from TokenOptions. -func (opts *TokenOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - if opts.Scope.ProjectName != "" { - // ProjectName provided: either DomainID or DomainName must also be supplied. - // ProjectID may not be supplied. - if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" { - //return nil, gophercloud.ErrScopeDomainIDOrDomainName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName") - return nil, err - } - if opts.Scope.ProjectID != "" { - //return nil, gophercloud.ErrScopeProjectIDOrProjectName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide at most one of ProjectID or ProjectName in a Scope") - return nil, err - } - - if opts.Scope.DomainID != "" { - // ProjectName + DomainID - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &opts.Scope.ProjectName, - "domain": map[string]interface{}{"id": &opts.Scope.DomainID}, - }, - }, nil - } - - if opts.Scope.DomainName != "" { - // ProjectName + DomainName - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &opts.Scope.ProjectName, - "domain": map[string]interface{}{"name": &opts.Scope.DomainName}, - }, - }, nil - } - } else if opts.Scope.ProjectID != "" { - // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. - if opts.Scope.DomainID != "" || opts.Scope.DomainName != "" { - //return nil, gophercloud.ErrScopeProjectIDAlone{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "ProjectID must be supplied alone in a Scope") - return nil, err - } - // if opts.Scope.DomainName != "" { - // return nil, gophercloud.ErrScopeProjectIDAlone{} - // } - - // ProjectID - return map[string]interface{}{ - "project": map[string]interface{}{ - "id": &opts.Scope.ProjectID, - }, - }, nil - } else if opts.Scope.DomainID != "" { - // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. - if opts.Scope.DomainName != "" { - //return nil, gophercloud.ErrScopeDomainIDOrDomainName{} - - err := huaweicloudsdk.NewSystemCommonError("Com.2000", "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName") - return nil, err - } - - // DomainID - return map[string]interface{}{ - "domain": map[string]interface{}{ - "id": &opts.Scope.DomainID, - }, - }, nil - } else if opts.Scope.DomainName != "" { - // DomainName - return map[string]interface{}{ - "domain": map[string]interface{}{ - "name": &opts.Scope.DomainName, - }, - }, nil - } - - return nil, nil -} - -// CanReauth ... -func (opts *TokenOptions) CanReauth() bool { - return opts.AllowReauth -} - -func subjectTokenHeaders(c *huaweicloudsdk.ServiceClient, subjectToken string) map[string]string { - return map[string]string{ - "X-Subject-Token": subjectToken, - } -} - -// Create authenticates and either generates a new token, or changes the Scope -// of an existing token. -func Create(c *huaweicloudsdk.ServiceClient, opts AuthOptionsBuilder) (r CreateResult) { - scope, err := opts.ToTokenV3ScopeMap() - if err != nil { - r.Err = err - return - } - - b, err := opts.ToTokenV3CreateMap(scope) - if err != nil { - r.Err = err - return - } - - resp, err := c.Post(tokenURL(c), b, &r.Body, &huaweicloudsdk.RequestOpts{ - MoreHeaders: map[string]string{"X-Auth-Token": ""}, - }) - r.Err = err - if resp != nil { - r.Header = resp.Header - } - return -} - -// Get validates and retrieves information about another token. -func Get(c *huaweicloudsdk.ServiceClient, token string) (r GetResult) { - resp, err := c.Get(tokenURL(c), &r.Body, &huaweicloudsdk.RequestOpts{ - MoreHeaders: subjectTokenHeaders(c, token), - OkCodes: []int{200, 203}, - }) - if resp != nil { - r.Err = err - r.Header = resp.Header - } - return -} - -// Validate determines if a specified token is valid or not. -func Validate(c *huaweicloudsdk.ServiceClient, token string) (bool, error) { - resp, err := c.Request("HEAD", tokenURL(c), &huaweicloudsdk.RequestOpts{ - MoreHeaders: subjectTokenHeaders(c, token), - OkCodes: []int{200, 204, 404}, - }) - if err != nil { - return false, err - } - - return resp.StatusCode == 200 || resp.StatusCode == 204, nil -} - -// Revoke immediately makes specified token invalid. -func Revoke(c *huaweicloudsdk.ServiceClient, token string) (r RevokeResult) { - _, r.Err = c.Delete(tokenURL(c), &huaweicloudsdk.RequestOpts{ - MoreHeaders: subjectTokenHeaders(c, token), - }) - return -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/results.go deleted file mode 100644 index 95ed9af61f30..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/results.go +++ /dev/null @@ -1,194 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tokens - -import ( - "time" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -// Endpoint represents a single API endpoint offered by a service. -// It matches either a public, internal or admin URL. -// If supported, it contains a region specifier, again if provided. -// The significance of the Region field will depend upon your provider. -type Endpoint struct { - ID string `json:"id"` - Region string `json:"region"` - RegionID string `json:"region_id"` - Interface string `json:"interface"` - URL string `json:"url"` -} - -// CatalogEntry provides a type-safe interface to an Identity API V3 service -// catalog listing. Each class of service, such as cloud DNS or block storage -// services, could have multiple CatalogEntry representing it (one by interface -// type, e.g public, admin or internal). -// -// Note: when looking for the desired service, try, whenever possible, to key -// off the type field. Otherwise, you'll tie the representation of the service -// to a specific provider. -type CatalogEntry struct { - // Service ID - ID string `json:"id"` - - // Name will contain the provider-specified name for the service. - Name string `json:"name"` - - // Type will contain a type string if OpenStack defines a type for the - // service. Otherwise, for provider-specific services, the provider may - // assign their own type strings. - Type string `json:"type"` - - // Endpoints will let the caller iterate over all the different endpoints that - // may exist for the service. - Endpoints []Endpoint `json:"endpoints"` -} - -// ServiceCatalog provides a view into the service catalog from a previous, -// successful authentication. -type ServiceCatalog struct { - Entries []CatalogEntry `json:"catalog"` -} - -// Domain provides information about the domain to which this token grants -// access. -type Domain struct { - ID string `json:"id"` - Name string `json:"name"` -} - -// User represents a user resource that exists in the Identity Service. -type User struct { - Domain Domain `json:"domain"` - ID string `json:"id"` - Name string `json:"name"` -} - -// Role provides information about roles to which User is authorized. -type Role struct { - ID string `json:"id"` - Name string `json:"name"` -} - -// Project provides information about project to which User is authorized. -type Project struct { - Domain Domain `json:"domain"` - ID string `json:"id"` - Name string `json:"name"` -} - -// commonResult is the response from a request. A commonResult has various -// methods which can be used to extract different details about the result. -type commonResult struct { - huaweicloudsdk.Result -} - -// Extract is a shortcut for ExtractToken. -// This function is deprecated and still present for backward compatibility. -func (r commonResult) Extract() (*Token, error) { - return r.ExtractToken() -} - -// ExtractToken interprets a commonResult as a Token. -func (r commonResult) ExtractToken() (*Token, error) { - var s Token - err := r.ExtractInto(&s) - if err != nil { - return nil, err - } - - // Parse the token itself from the stored headers. - s.ID = r.Header.Get("X-Subject-Token") - - return &s, err -} - -// ExtractTokenID implements the gophercloud.AuthResult interface. The returned -// string is the same as the ID field of the Token struct returned from -// ExtractToken(). -func (r CreateResult) ExtractTokenID() (string, error) { - return r.Header.Get("X-Subject-Token"), r.Err -} - -// ExtractServiceCatalog returns the ServiceCatalog that was generated along -// with the user's Token. -func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) { - var s ServiceCatalog - err := r.ExtractInto(&s) - return &s, err -} - -// ExtractUser returns the User that is the owner of the Token. -func (r commonResult) ExtractUser() (*User, error) { - var s struct { - User *User `json:"user"` - } - err := r.ExtractInto(&s) - return s.User, err -} - -// ExtractRoles returns Roles to which User is authorized. -func (r commonResult) ExtractRoles() ([]Role, error) { - var s struct { - Roles []Role `json:"roles"` - } - err := r.ExtractInto(&s) - return s.Roles, err -} - -// ExtractProject returns Project to which User is authorized. -func (r commonResult) ExtractProject() (*Project, error) { - var s struct { - Project *Project `json:"project"` - } - err := r.ExtractInto(&s) - return s.Project, err -} - -// CreateResult is the response from a Create request. Use ExtractToken() -// to interpret it as a Token, or ExtractServiceCatalog() to interpret it -// as a service catalog. -type CreateResult struct { - commonResult -} - -// GetResult is the response from a Get request. Use ExtractToken() -// to interpret it as a Token, or ExtractServiceCatalog() to interpret it -// as a service catalog. -type GetResult struct { - commonResult -} - -// RevokeResult is response from a Revoke request. -type RevokeResult struct { - commonResult -} - -// Token is a string that grants a user access to a controlled set of services -// in an OpenStack provider. Each Token is valid for a set length of time. -type Token struct { - // ID is the issued token. - ID string `json:"id"` - - // ExpiresAt is the timestamp at which this token will no longer be accepted. - ExpiresAt time.Time `json:"expires_at"` -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.ExtractIntoStructPtr(v, "token") -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/urls.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/urls.go deleted file mode 100644 index 5ee19d4d883c..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/identity/v3/tokens/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 tokens - -import "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" - -func tokenURL(c *huaweicloudsdk.ServiceClient) string { - return c.ServiceURL("auth", "tokens") -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/utils/choose_version.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/utils/choose_version.go deleted file mode 100644 index 509fd3121772..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/openstack/utils/choose_version.go +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 utils - -import ( - "fmt" - "strings" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -// Version is a supported API version, corresponding to a vN package within the appropriate service. -type Version struct { - ID string - Suffix string - Priority int -} - -var goodStatus = map[string]bool{ - "current": true, - "supported": true, - "stable": true, -} - -// ChooseVersion queries the base endpoint of an API to choose the most recent non-experimental alternative from a service's -// published versions. -// It returns the highest-Priority Version among the alternatives that are provided, as well as its corresponding endpoint. -func ChooseVersion(client *huaweicloudsdk.ProviderClient, recognized []*Version) (*Version, string, error) { - type linkResp struct { - Href string `json:"href"` - Rel string `json:"rel"` - } - - type valueResp struct { - ID string `json:"id"` - Status string `json:"status"` - Links []linkResp `json:"links"` - } - - type versionsResp struct { - Values []valueResp `json:"values"` - } - - type response struct { - Versions versionsResp `json:"versions"` - } - - normalize := func(endpoint string) string { - if !strings.HasSuffix(endpoint, "/") { - return endpoint + "/" - } - return endpoint - } - identityEndpoint := normalize(client.IdentityEndpoint) - - // If a full endpoint is specified, check version suffixes for a match first. - for _, v := range recognized { - if strings.HasSuffix(identityEndpoint, v.Suffix) { - return v, identityEndpoint, nil - } - } - - var resp response - _, err := client.Request("GET", client.IdentityBase, &huaweicloudsdk.RequestOpts{ - JSONResponse: &resp, - OkCodes: []int{200, 300}, - }) - - if err != nil { - return nil, "", err - } - - var highest *Version - var endpoint string - - for _, value := range resp.Versions.Values { - href := "" - for _, link := range value.Links { - if link.Rel == "self" { - href = normalize(link.Href) - } - } - - for _, version := range recognized { - if strings.Contains(value.ID, version.ID) { - // Prefer a version that exactly matches the provided endpoint. - if href == identityEndpoint { - if href == "" { - return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, client.IdentityBase) - } - return version, href, nil - } - - // Otherwise, find the highest-priority version with a whitelisted status. - if goodStatus[strings.ToLower(value.Status)] { - if highest == nil || version.Priority > highest.Priority { - highest = version - endpoint = href - } - } - } - } - } - - if highest == nil { - return nil, "", fmt.Errorf("No supported version available from endpoint %s", client.IdentityBase) - } - if endpoint == "" { - return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", highest.ID, client.IdentityBase) - } - - return highest, endpoint, nil -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/http.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/http.go deleted file mode 100644 index 2ad6350dbed5..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/http.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 pagination - -import ( - "encoding/json" - "io/ioutil" - "net/http" - "net/url" - "strings" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -// PageResult stores the HTTP response that returned the current page of results. -type PageResult struct { - huaweicloudsdk.Result - url.URL -} - -// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the -// results, interpreting it as JSON if the content type indicates. -func PageResultFrom(resp *http.Response) (PageResult, error) { - var parsedBody interface{} - - defer resp.Body.Close() - rawBody, err := ioutil.ReadAll(resp.Body) - if err != nil { - return PageResult{}, err - } - - if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { - err = json.Unmarshal(rawBody, &parsedBody) - if err != nil { - return PageResult{}, err - } - } else { - parsedBody = rawBody - } - - return PageResultFromParsed(resp, parsedBody), err -} - -// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its -// body parsed as JSON (and closed). -func PageResultFromParsed(resp *http.Response, body interface{}) PageResult { - return PageResult{ - Result: huaweicloudsdk.Result{ - Body: body, - Header: resp.Header, - }, - URL: *resp.Request.URL, - } -} - -// Request performs an HTTP request and extracts the http.Response from the result. -func Request(client *huaweicloudsdk.ServiceClient, headers map[string]string, url string) (*http.Response, error) { - return client.Get(url, nil, &huaweicloudsdk.RequestOpts{ - MoreHeaders: headers, - OkCodes: []int{200, 204, 300}, - }) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/linked.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/linked.go deleted file mode 100644 index e5c8c9538640..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/linked.go +++ /dev/null @@ -1,147 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 pagination - -import ( - "fmt" - "reflect" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result. -type LinkedPageBase struct { - PageResult - - // LinkPath lists the keys that should be traversed within a response to arrive at the "next" pointer. - // If any link along the path is missing, an empty URL will be returned. - // If any link results in an unexpected value type, an error will be returned. - // When left as "nil", []string{"links", "next"} will be used as a default. - LinkPath []string -} - -// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present. -// It assumes that the links are available in a "links" element of the top-level response object. -// If this is not the case, override NextPageURL on your result type. -func (current LinkedPageBase) NextPageURL() (string, error) { - var path []string - var key string - - if current.LinkPath == nil { - path = []string{"links", "next"} - } else { - path = current.LinkPath - } - - submap, ok := current.Body.(map[string]interface{}) - if !ok { - // err := gophercloud.ErrUnexpectedType{} - // err.Expected = "map[string]interface{}" - // err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - // return "", err - - expected := "map[string]interface{}" - actual := fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - message := fmt.Sprintf(huaweicloudsdk.CEErrUnexpectedTypeMessage, expected, actual) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEErrUnexpectedTypeCode, message) - return "", err - } - - for { - key, path = path[0], path[1:] - - value, ok := submap[key] - if !ok { - return "", nil - } - - if len(path) > 0 { - submap, ok = value.(map[string]interface{}) - if !ok { - // err := gophercloud.ErrUnexpectedType{} - // err.Expected = "map[string]interface{}" - // err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) - // return "", err - - expected := "map[string]interface{}" - actual := fmt.Sprintf("%v", reflect.TypeOf(value)) - message := fmt.Sprintf(huaweicloudsdk.CEErrUnexpectedTypeMessage, expected, actual) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEErrUnexpectedTypeCode, message) - return "", err - } - } else { - if value == nil { - // Actual null element. - return "", nil - } - - url, ok := value.(string) - if !ok { - // err := gophercloud.ErrUnexpectedType{} - // err.Expected = "string" - // err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) - // return "", err - - expected := "string" - actual := fmt.Sprintf("%v", reflect.TypeOf(value)) - message := fmt.Sprintf(huaweicloudsdk.CEErrUnexpectedTypeMessage, expected, actual) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEErrUnexpectedTypeCode, message) - return "", err - } - - return url, nil - } - } -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current LinkedPageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - // err := gophercloud.ErrUnexpectedType{} - // err.Expected = "[]interface{}" - // err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - // return true, err - - expected := "[]interface{}" - actual := fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - message := fmt.Sprintf(huaweicloudsdk.CEErrUnexpectedTypeMessage, expected, actual) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEErrUnexpectedTypeCode, message) - return true, err -} - -// GetBody returns the linked page's body. This method is needed to satisfy the -// Page interface. -func (current LinkedPageBase) GetBody() interface{} { - return current.Body -} - -// WrapNextPageURL function use makerID to warp next page url,it returns the full url for request. -func (current LinkedPageBase) WrapNextPageURL(markerID string) (string, error) { - limit := current.URL.Query().Get("limit") - - if limit == "" { - return "", nil - } - - q := current.URL.Query() - - q.Set("marker", markerID) - current.URL.RawQuery = q.Encode() - return current.URL.String(), nil -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/pager.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/pager.go deleted file mode 100644 index 8f219ee7f755..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/pagination/pager.go +++ /dev/null @@ -1,273 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 pagination - -import ( - //"errors" - "fmt" - "net/http" - "reflect" - "strings" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go" -) - -//var ( -// // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. -// ErrPageNotAvailable = errors.New("The requested page does not exist.") -//) - -// Page must be satisfied by the result type of any resource collection. -// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated. -// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs, -// instead. -// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type -// will need to implement. -type Page interface { - // NextPageURL generates the URL for the page of data that follows this collection. - // Return "" if no such page exists. - NextPageURL() (string, error) - - // IsEmpty returns true if this Page has no items in it. - IsEmpty() (bool, error) - - // GetBody returns the Page Body. This is used in the `AllPages` method. - GetBody() interface{} -} - -// Pager knows how to advance through a specific resource collection, one page at a time. -type Pager struct { - client *huaweicloudsdk.ServiceClient - - initialURL string - - createPage func(r PageResult) Page - - firstPage Page - - Err error - - // Headers supplies additional HTTP headers to populate on each paged request. - Headers map[string]string -} - -// NewPager constructs a manually-configured pager. -// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page. -func NewPager(client *huaweicloudsdk.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager { - return Pager{ - client: client, - initialURL: initialURL, - createPage: createPage, - } -} - -// WithPageCreator returns a new Pager that substitutes a different page creation function. This is -// useful for overriding List functions in delegation. -func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager { - return Pager{ - client: p.client, - initialURL: p.initialURL, - createPage: createPage, - } -} - -func (p Pager) fetchNextPage(url string) (Page, error) { - resp, err := Request(p.client, p.Headers, url) - if err != nil { - return nil, err - } - - remembered, err := PageResultFrom(resp) - if err != nil { - return nil, err - } - - return p.createPage(remembered), nil -} - -// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function. -// Return "false" from the handler to prematurely stop iterating. -func (p Pager) EachPage(handler func(Page) (bool, error)) error { - if p.Err != nil { - return p.Err - } - currentURL := p.initialURL - for { - var currentPage Page - - // if first page has already been fetched, no need to fetch it again - if p.firstPage != nil { - currentPage = p.firstPage - p.firstPage = nil - } else { - var err error - currentPage, err = p.fetchNextPage(currentURL) - if err != nil { - return err - } - } - - empty, err := currentPage.IsEmpty() - if err != nil { - return err - } - if empty { - return nil - } - - ok, err := handler(currentPage) - if err != nil { - return err - } - if !ok { - return nil - } - - currentURL, err = currentPage.NextPageURL() - if err != nil { - return err - } - if currentURL == "" { - return nil - } - } -} - -// AllPages returns all the pages from a `List` operation in a single page, -// allowing the user to retrieve all the pages at once. -func (p Pager) AllPages() (Page, error) { - // pagesSlice holds all the pages until they get converted into as Page Body. - var pagesSlice []interface{} - // body will contain the final concatenated Page body. - var body reflect.Value - - // Grab a first page to ascertain the page body type. - firstPage, err := p.fetchNextPage(p.initialURL) - if err != nil { - return nil, err - } - // Store the page type so we can use reflection to create a new mega-page of - // that type. - pageType := reflect.TypeOf(firstPage) - - // if it's a single page, just return the firstPage (first page) - if _, found := pageType.FieldByName("SinglePageBase"); found { - return firstPage, nil - } - - // store the first page to avoid getting it twice - p.firstPage = firstPage - - // Switch on the page body type. Recognized types are `map[string]interface{}`, - // `[]byte`, and `[]interface{}`. - switch pb := firstPage.GetBody().(type) { - case map[string]interface{}: - // key is the map key for the page body if the body type is `map[string]interface{}`. - var key string - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().(map[string]interface{}) - for k, v := range b { - // If it's a linked page, we don't want the `links`, we want the other one. - if !strings.HasSuffix(k, "links") { - // check the field's type. we only want []interface{} (which is really []map[string]interface{}) - switch vt := v.(type) { - case []interface{}: - key = k - pagesSlice = append(pagesSlice, vt...) - } - } - } - return true, nil - }) - if err != nil { - return nil, err - } - // Set body to value of type `map[string]interface{}` - body = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(key), reflect.TypeOf(pagesSlice))) - body.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(pagesSlice)) - case []byte: - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().([]byte) - pagesSlice = append(pagesSlice, b) - // separate pages with a comma - pagesSlice = append(pagesSlice, []byte{10}) - return true, nil - }) - if err != nil { - return nil, err - } - if len(pagesSlice) > 0 { - // Remove the trailing comma. - pagesSlice = pagesSlice[:len(pagesSlice)-1] - } - var b []byte - // Combine the slice of slices in to a single slice. - for _, slice := range pagesSlice { - b = append(b, slice.([]byte)...) - } - // Set body to value of type `bytes`. - body = reflect.New(reflect.TypeOf(b)).Elem() - body.SetBytes(b) - case []interface{}: - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().([]interface{}) - pagesSlice = append(pagesSlice, b...) - return true, nil - }) - if err != nil { - return nil, err - } - // Set body to value of type `[]interface{}` - body = reflect.MakeSlice(reflect.TypeOf(pagesSlice), len(pagesSlice), len(pagesSlice)) - for i, s := range pagesSlice { - body.Index(i).Set(reflect.ValueOf(s)) - } - default: - // err := gophercloud.ErrUnexpectedType{} - // err.Expected = "map[string]interface{}/[]byte/[]interface{}" - // err.Actual = fmt.Sprintf("%T", pb) - // return nil, err - - expected := "map[string]interface{}/[]byte/[]interface{}" - actual := fmt.Sprintf("%T", pb) - message := fmt.Sprintf(huaweicloudsdk.CEErrUnexpectedTypeMessage, expected, actual) - err := huaweicloudsdk.NewSystemCommonError(huaweicloudsdk.CEErrUnexpectedTypeCode, message) - return nil, err - } - - // Each `Extract*` function is expecting a specific type of page coming back, - // otherwise the type assertion in those functions will fail. pageType is needed - // to create a type in this method that has the same type that the `Extract*` - // function is expecting and set the Body of that object to the concatenated - // pages. - page := reflect.New(pageType) - // Set the page body to be the concatenated pages. - page.Elem().FieldByName("Body").Set(body) - // Set any additional headers that were pass along. The `objectstorage` package, - // for example, passes a Content-Type header. - h := make(http.Header) - for k, v := range p.Headers { - h.Add(k, v) - } - page.Elem().FieldByName("Header").Set(reflect.ValueOf(h)) - // Type assert the page to a Page interface so that the type assertion in the - // `Extract*` methods will work. - return page.Elem().Interface().(Page), err -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/params.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/params.go deleted file mode 100644 index adc1d016394a..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/params.go +++ /dev/null @@ -1,494 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "encoding/json" - "fmt" - "net/url" - "reflect" - "strconv" - "strings" - "time" -) - -/* -BuildRequestBody builds a map[string]interface from the given `struct`. If -parent is not an empty string, the final map[string]interface returned will -encapsulate the built one. For example: - - disk := 1 - createOpts := flavors.CreateOpts{ - ID: "1", - Name: "m1.tiny", - Disk: &disk, - RAM: 512, - VCPUs: 1, - RxTxFactor: 1.0, - } - - body, err := gophercloud.BuildRequestBody(createOpts, "flavor") - -The above example can be run as-is, however it is recommended to look at how -BuildRequestBody is used within Gophercloud to more fully understand how it -fits within the request process as a whole rather than use it directly as shown -above. -*/ -func BuildRequestBody(opts interface{}, parent string) (map[string]interface{}, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]interface{}) - if optsValue.Kind() == reflect.Struct { - //fmt.Printf("optsValue.Kind() is a reflect.Struct: %+v\n", optsValue.Kind()) - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - - if f.Name != strings.Title(f.Name) { - continue - } - - zero := isZero(v) - - // if the field has a required tag that's set to "true" - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - //fmt.Printf("Checking required field [%s]:\n\tv: %+v\n\tisZero:%v\n", f.Name, v.Interface(), zero) - // if the field's value is zero, return a missing-argument error - if zero { - // if the field has a 'required' tag, it can't have a zero-value - message := fmt.Sprintf(CEMissingInputMessage, f.Name) - err := NewSystemCommonError(CEMissingInputCode, message) - return nil, err - } - } - - if xorTag := f.Tag.Get("xor"); xorTag != "" { - //fmt.Printf("Checking `xor` tag for field [%s] with value %+v:\n\txorTag: %s\n", f.Name, v, xorTag) - xorField := optsValue.FieldByName(xorTag) - var xorFieldIsZero bool - if reflect.ValueOf(xorField.Interface()) == reflect.Zero(xorField.Type()) { - xorFieldIsZero = true - } else { - if xorField.Kind() == reflect.Ptr { - xorField = xorField.Elem() - } - xorFieldIsZero = isZero(xorField) - } - if !(zero != xorFieldIsZero) { - message := fmt.Sprintf(CEMissingInputMessage, fmt.Sprintf("%s/%s", f.Name, xorTag)) - err := NewSystemCommonError(CEMissingInputCode, message) - return nil, err - } - } - - if orTag := f.Tag.Get("or"); orTag != "" { - if zero { - orField := optsValue.FieldByName(orTag) - var orFieldIsZero bool - if reflect.ValueOf(orField.Interface()) == reflect.Zero(orField.Type()) { - orFieldIsZero = true - } else { - if orField.Kind() == reflect.Ptr { - orField = orField.Elem() - } - orFieldIsZero = isZero(orField) - } - if orFieldIsZero { - message := fmt.Sprintf(CEMissingInputMessage, fmt.Sprintf("%s/%s", f.Name, orTag)) - err := NewSystemCommonError(CEMissingInputCode, message) - return nil, err - } - } - } - - jsonTag := f.Tag.Get("json") - if jsonTag == "-" { - continue - } - - if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) { - if zero { - //fmt.Printf("value before change: %+v\n", optsValue.Field(i)) - if jsonTag != "" { - jsonTagPieces := strings.Split(jsonTag, ",") - if len(jsonTagPieces) > 1 && jsonTagPieces[1] == "omitempty" { - if v.CanSet() { - if !v.IsNil() { - if v.Kind() == reflect.Ptr { - v.Set(reflect.Zero(v.Type())) - } - } - //fmt.Printf("value after change: %+v\n", optsValue.Field(i)) - } - } - } - continue - } - - //fmt.Printf("Calling BuildRequestBody with:\n\tv: %+v\n\tf.Name:%s\n", v.Interface(), f.Name) - _, err := BuildRequestBody(v.Interface(), f.Name) - if err != nil { - return nil, err - } - } - } - - //fmt.Printf("opts: %+v \n", opts) - - b, err := json.Marshal(opts) - if err != nil { - return nil, err - } - - //fmt.Printf("string(b): %s\n", string(b)) - - err = json.Unmarshal(b, &optsMap) - if err != nil { - return nil, err - } - - //fmt.Printf("optsMap: %+v\n", optsMap) - - if parent != "" { - optsMap = map[string]interface{}{parent: optsMap} - } - //fmt.Printf("optsMap after parent added: %+v\n", optsMap) - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - //return nil, fmt.Errorf("Options type is not a struct.") - - err := NewSystemCommonError(CEOptionTypeNotStructCode, CEOptionTypeNotStructMessage) - return nil, err -} - -// EnabledState is a convenience type, mostly used in Create and Update -// operations. Because the zero value of a bool is FALSE, we need to use a -// pointer instead to indicate zero-ness. -type EnabledState *bool - -// Convenience vars for EnabledState values. -var ( - iTrue = true - iFalse = false - - Enabled EnabledState = &iTrue - Disabled EnabledState = &iFalse -) - -// IPVersion is a type for the possible IP address versions. Valid instances -// are IPv4 and IPv6 -type IPVersion int - -const ( - // IPv4 is used for IP version 4 addresses - IPv4 IPVersion = 4 - // IPv6 is used for IP version 6 addresses - IPv6 IPVersion = 6 -) - -// IntToPointer is a function for converting integers into integer pointers. -// This is useful when passing in options to operations. -func IntToPointer(i int) *int { - return &i -} - -/* -MaybeString is an internal function to be used by request methods in individual -resource packages. - -It takes a string that might be a zero value and returns either a pointer to its -address or nil. This is useful for allowing users to conveniently omit values -from an options struct by leaving them zeroed, but still pass nil to the JSON -serializer so they'll be omitted from the request body. -*/ -func MaybeString(original string) *string { - if original != "" { - return &original - } - return nil -} - -/* -MaybeInt is an internal function to be used by request methods in individual -resource packages. - -Like MaybeString, it accepts an int that may or may not be a zero value, and -returns either a pointer to its address or nil. It's intended to hint that the -JSON serializer should omit its field. -*/ -func MaybeInt(original int) *int { - if original != 0 { - return &original - } - return nil -} - -/* -func isUnderlyingStructZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Ptr: - return isUnderlyingStructZero(v.Elem()) - default: - return isZero(v) - } -} -*/ - -var t time.Time - -func isZero(v reflect.Value) bool { - //fmt.Printf("\n\nchecking isZero for value: %+v\n", v) - switch v.Kind() { - case reflect.Ptr: - if v.IsNil() { - return true - } - return false - case reflect.Func, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - z := true - for i := 0; i < v.Len(); i++ { - z = z && isZero(v.Index(i)) - } - return z - case reflect.Struct: - if v.Type() == reflect.TypeOf(t) { - if v.Interface().(time.Time).IsZero() { - return true - } - return false - } - z := true - for i := 0; i < v.NumField(); i++ { - z = z && isZero(v.Field(i)) - } - return z - } - // Compare other types directly: - z := reflect.Zero(v.Type()) - //fmt.Printf("zero type for value: %+v\n\n\n", z) - return v.Interface() == z.Interface() -} - -/* -BuildQueryString is an internal function to be used by request methods in -individual resource packages. - -It accepts a tagged structure and expands it into a URL struct. Field names are -converted into query parameters based on a "q" tag. For example: - - type struct Something { - Bar string `q:"x_bar"` - Baz int `q:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into "?x_bar=AAA&lorem_ipsum=BBB". - -The struct's fields may be strings, integers, or boolean values. Fields left at -their type's zero value will be omitted from the query. -*/ -func BuildQueryString(opts interface{}) (*url.URL, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - params := url.Values{} - - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - qTag := f.Tag.Get("q") - - // if the field has a 'q' tag, it goes in the query string - if qTag != "" { - tags := strings.Split(qTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - loop: - switch v.Kind() { - case reflect.Ptr: - v = v.Elem() - goto loop - case reflect.String: - params.Add(tags[0], v.String()) - case reflect.Int: - params.Add(tags[0], strconv.FormatInt(v.Int(), 10)) - case reflect.Bool: - params.Add(tags[0], strconv.FormatBool(v.Bool())) - case reflect.Slice: - switch v.Type().Elem() { - case reflect.TypeOf(0): - for i := 0; i < v.Len(); i++ { - params.Add(tags[0], strconv.FormatInt(v.Index(i).Int(), 10)) - } - default: - for i := 0; i < v.Len(); i++ { - params.Add(tags[0], v.Index(i).String()) - } - } - case reflect.Map: - if v.Type().Key().Kind() == reflect.String && v.Type().Elem().Kind() == reflect.String { - var s []string - for _, k := range v.MapKeys() { - value := v.MapIndex(k).String() - s = append(s, fmt.Sprintf("'%s':'%s'", k.String(), value)) - } - params.Add(tags[0], fmt.Sprintf("{%s}", strings.Join(s, ", "))) - } - } - } else { - // Otherwise, the field is not set. - if len(tags) == 2 && tags[1] == "required" { - // And the field is required. Return an error. - return &url.URL{}, fmt.Errorf("Required query parameter [%s] not set.", f.Name) - } - } - } - } - - return &url.URL{RawQuery: params.Encode()}, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - //return nil, fmt.Errorf("Options type is not a struct.") - - err := NewSystemCommonError(CEOptionTypeNotStructCode, CEOptionTypeNotStructMessage) - return nil, err -} - -/* -BuildHeaders is an internal function to be used by request methods in -individual resource packages. - -It accepts an arbitrary tagged structure and produces a string map that's -suitable for use as the HTTP headers of an outgoing request. Field names are -mapped to header names based in "h" tags. - - type struct Something { - Bar string `h:"x_bar"` - Baz int `h:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into: - - map[string]string{ - "x_bar": "AAA", - "lorem_ipsum": "BBB", - } - -Untagged fields and fields left at their zero values are skipped. Integers, -booleans and string values are supported. -*/ -func BuildHeaders(opts interface{}) (map[string]string, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]string) - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - hTag := f.Tag.Get("h") - - // if the field has a 'h' tag, it goes in the header - if hTag != "" { - tags := strings.Split(hTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - switch v.Kind() { - case reflect.String: - optsMap[tags[0]] = v.String() - case reflect.Int: - optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) - case reflect.Bool: - optsMap[tags[0]] = strconv.FormatBool(v.Bool()) - } - } else { - // Otherwise, the field is not set. - if len(tags) == 2 && tags[1] == "required" { - // And the field is required. Return an error. - return optsMap, fmt.Errorf("Required header not set.") - } - } - } - - } - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - //return optsMap, fmt.Errorf("Options type is not a struct.") - - err := NewSystemCommonError(CEOptionTypeNotStructCode, CEOptionTypeNotStructMessage) - return optsMap, err -} - -// IDSliceToQueryString takes a slice of elements and converts them into a query -// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the -// result would be `?name=20&name=40&name=60' -func IDSliceToQueryString(name string, ids []int) string { - str := "" - for k, v := range ids { - if k == 0 { - str += "?" - } else { - str += "&" - } - str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v)) - } - return str -} - -// IntWithinRange returns TRUE if an integer falls within a defined range, and -// FALSE if not. -func IntWithinRange(val, min, max int) bool { - return val > min && val < max -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/provider_client.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/provider_client.go deleted file mode 100644 index 51af4dbba565..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/provider_client.go +++ /dev/null @@ -1,467 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - - //"strconv" - "strings" - "sync" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk" -) - -// DefaultUserAgent is the default User-Agent string set in the request header. -const DefaultUserAgent = "huawei-cloud-sdk-go/1.0.20" - -// ProviderClient stores details that are required to interact with any -// services within a specific provider's API. -// -// Generally, you acquire a ProviderClient by calling the NewClient method in -// the appropriate provider's child package, providing whatever authentication -// credentials are required. -type ProviderClient struct { - // IdentityBase is the base URL used for a particular provider's identity - // service - it will be used when issuing authenticatation requests. It - // should point to the root resource of the identity service, not a specific - // identity version. - IdentityBase string - - // IdentityEndpoint is the identity endpoint. This may be a specific version - // of the identity service. If this is the case, this endpoint is used rather - // than querying versions first. - IdentityEndpoint string - - // TokenID is the ID of the most recently issued valid token. - // NOTE: Aside from within a custom ReauthFunc, this field shouldn't be set by an application. - // To safely read or write this value, call `Token` or `SetToken`, respectively - TokenID string - - // EndpointLocator describes how this provider discovers the endpoints for - // its constituent services. - EndpointLocator EndpointLocator - - // HTTPClient allows users to interject arbitrary http, https, or other transit behaviors. - HTTPClient http.Client - - // UserAgent represents the User-Agent header in the HTTP request. - UserAgent UserAgent - - // ReauthFunc is the function used to re-authenticate the user if the request - // fails with a 401 HTTP response code. This a needed because there may be multiple - // authentication functions for different Identity service versions. - ReauthFunc func() error - - // mut is a mutex for the client. It protects read and write access to client attributes such as getting - // and setting the TokenID. - mut *sync.RWMutex - - // reauthmut is a mutex for reauthentication it attempts to ensure that only one reauthentication - // attempt happens at one time. - reauthmut *reauthlock - - // DomainID - DomainID string - - // ProjectID - ProjectID string - - // Conf define the configs parameter of the provider client - Conf *Config - - // AKSKAuthOptions provides the value for AK/SK authentication, it should be nil if you use token authentication, - // Otherwise, it must have a value - AKSKOptions aksk.AKSKOptions -} - -// reauthlock represents a set of attributes used to help in the reauthentication process. -type reauthlock struct { - sync.RWMutex - reauthing bool -} - -// GetProjectID Implement the GetProjectID() interface, return client projectID. -func (client *ProviderClient) GetProjectID() string { - return client.ProjectID -} - -// AuthenticatedHeaders returns a map of HTTP headers that are common for all -// authenticated service requests. -func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) { - if client.reauthmut != nil { - client.reauthmut.RLock() - if client.reauthmut.reauthing { - client.reauthmut.RUnlock() - return - } - client.reauthmut.RUnlock() - } - t := client.Token() - if t == "" { - return - } - return map[string]string{"X-Auth-Token": t} -} - -// UseTokenLock creates a mutex that is used to allow safe concurrent access to the auth token. -// If the application's ProviderClient is not used concurrently, this doesn't need to be called. -func (client *ProviderClient) UseTokenLock() { - client.mut = new(sync.RWMutex) - client.reauthmut = new(reauthlock) -} - -// Token safely reads the value of the auth token from the ProviderClient. Applications should -// call this method to access the token instead of the TokenID field -func (client *ProviderClient) Token() string { - if client.mut != nil { - client.mut.RLock() - defer client.mut.RUnlock() - } - return client.TokenID -} - -// SetToken safely sets the value of the auth token in the ProviderClient. Applications may -// use this method in a custom ReauthFunc -func (client *ProviderClient) SetToken(t string) { - if client.mut != nil { - client.mut.Lock() - defer client.mut.Unlock() - } - client.TokenID = t -} - -//Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is -//called because of a 401 response, the caller may pass the previous token. In -//this case, the reauthentication can be skipped if another thread has already -//reauthenticated in the meantime. If no previous token is known, an empty -//string should be passed instead to force unconditional reauthentication. -func (client *ProviderClient) Reauthenticate(previousToken string) (err error) { - if client.ReauthFunc == nil { - return nil - } - - if client.mut == nil { - return client.ReauthFunc() - } - client.mut.Lock() - defer client.mut.Unlock() - - client.reauthmut.Lock() - client.reauthmut.reauthing = true - client.reauthmut.Unlock() - - if previousToken == "" || client.TokenID == previousToken { - err = client.ReauthFunc() - } - - client.reauthmut.Lock() - client.reauthmut.reauthing = false - client.reauthmut.Unlock() - return -} - -// RequestOpts customizes the behavior of the provider.Request() method. -type RequestOpts struct { - // JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The - // content type of the request will default to "application/json" unless overridden by MoreHeaders. - // It's an error to specify both a JSONBody and a RawBody. - JSONBody interface{} - // RawBody contains an io.Reader that will be consumed by the request directly. No content-type - // will be set unless one is provided explicitly by MoreHeaders. - RawBody io.Reader - // JSONResponse, if provided, will be populated with the contents of the response body parsed as - // JSON. - JSONResponse interface{} - // OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If - // the response has a different code, an error will be returned. - OkCodes []int - // MoreHeaders specifies additional HTTP headers to be provide on the request. If a header is - // provided with a blank value (""), that header will be *omitted* instead: use this to suppress - // the default Accept header or an inferred Content-Type, for example. - MoreHeaders map[string]string - // ErrorContext specifies the resource error type to return if an error is encountered. - // This lets resources override default error messages based on the response status code. - ErrorContext error - - HandleError func(httpStatus int, responseContent string) error -} - -var applicationJSON = "application/json" - -// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication -// header will automatically be provided. -func (client *ProviderClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { - req, err := buildReq(client, method, url, options) - if err != nil { - return nil, err - } - log := GetLogger() - prereqtok := req.Header.Get("X-Auth-Token") - var resp *http.Response - - /* - //根据配置执行超时重连 - for retryTimes := 0; retryTimes <= client.Conf.MaxRetryTime; retryTimes++ { - resp, err = client.HTTPClient.Do(req) - - var timeout bool - // receive error - if err != nil { - if timeout = isTimeout(err); !timeout { - //fmt.Println("timeout:", timeout) - // if not timeout error, return - return nil, err - } else if retryTimes >= client.Conf.MaxRetryTime { - timeoutErrorMsg := fmt.Sprintf(CETimeoutErrorMessage, strconv.Itoa(retryTimes+1), strconv.Itoa(retryTimes+1)) - err := NewSystemCommonError(CETimeoutErrorCode, timeoutErrorMsg) - return nil, err - } - } - - // if status code >= 500 or timeout, will trigger retry - if client.Conf.AutoRetry && (timeout || isServerError(resp)) { - req, err = buildReq(client, method, url, options) - if err != nil { - return nil, err - } - - continue - } - break - } - */ - - //fmt.Println("url:", url) - //Issue the request. 原代码,注释掉 - resp, err = client.HTTPClient.Do(req) - if err != nil { - log.Debug("Request error", err) - return nil, err - } - - log.Debug("Request method is %s,Request url is %s", req.Method, url) - log.Debug("Request header is %s", req.Header) - log.Debug("Response status code is %d", resp.StatusCode) - log.Debug("Response header is %s", resp.Header) - bodyBytes, _ := ioutil.ReadAll(resp.Body) - resp.Body.Close() // must close - resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) - - log.Debug("Response body is %s\n", string(bodyBytes)) - - // Allow default OkCodes if none explicitly set - if options.OkCodes == nil { - options.OkCodes = defaultOkCodes(method) - } - - // Validate the HTTP response status. - var ok bool - for _, code := range options.OkCodes { - if resp.StatusCode == code { - ok = true - break - } - } - if !ok { - body, _ := ioutil.ReadAll(resp.Body) - resp.Body.Close() - log.Debug("Request failed response body is %s", string(body)) - /* - http.StatusBadRequest: //400 - http.StatusUnauthorized: //401 - http.StatusForbidden: //403 - http.StatusNotFound: //404 - http.StatusMethodNotAllowed: //405 - http.StatusRequestTimeout: //408 - http.StatusConflict: //409 - http.StatusTooManyRequests: //429 - http.StatusInternalServerError: //500 - http.StatusServiceUnavailable: //503 - */ - switch resp.StatusCode { - case http.StatusUnauthorized: //401 - if client.ReauthFunc != nil { - return doReauthAndReq(client, prereqtok, method, url, options) - } - case http.StatusForbidden: - b := strings.Contains(string(body), "Token need to refresh") - if client.ReauthFunc != nil && b { - return doReauthAndReq(client, prereqtok, method, url, options) - } - } - - if options.HandleError != nil { - return resp, options.HandleError(resp.StatusCode, string(body)) - } - - return resp, NewSystemServerError(resp.StatusCode, string(body)) - } - - // Parse the response body as JSON, if requested to do so. - if options.JSONResponse != nil { - defer resp.Body.Close() - if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil { - return nil, err - } - } - return resp, nil -} - -//构造request对象 -func buildReq(client *ProviderClient, method, url string, options *RequestOpts) (*http.Request, error) { - var body io.Reader - var contentType *string - - // Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided - // io.ReadSeeker as-is. Default the content-type to application/json. - if options.JSONBody != nil { - if options.RawBody != nil { - panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().") - } - - rendered, err := json.Marshal(options.JSONBody) - if err != nil { - return nil, err - } - GetLogger().Debug("Request body is %s", string(rendered)) - body = bytes.NewReader(rendered) - contentType = &applicationJSON - } - - if options.RawBody != nil { - body = options.RawBody - } - - // Construct the http.Request. - req, err := http.NewRequest(method, url, body) - if err != nil { - return nil, err - } - - // Populate the request headers. Apply options.MoreHeaders last, to give the caller the chance to - // modify or omit any header. - if contentType != nil { - req.Header.Set("Content-Type", *contentType) - } - req.Header.Set("Accept", applicationJSON) - - // Set the User-Agent header - req.Header.Set("User-Agent", client.UserAgent.Join()) - - if options.MoreHeaders != nil { - for k, v := range options.MoreHeaders { - if v != "" { - req.Header.Set(k, v) - } else { - req.Header.Del(k) - } - } - } - - // get latest token from client - for k, v := range client.AuthenticatedHeaders() { - req.Header.Set(k, v) - } - - if client.AKSKOptions.AccessKey != "" { - aksk.Sign(req, aksk.SignOptions{ - AccessKey: client.AKSKOptions.AccessKey, - SecretKey: client.AKSKOptions.SecretKey, - }) - } - - // Set connection parameter to close the connection immediately when we've got the response - req.Close = true - - return req, nil -} - -//reauth and request -func doReauthAndReq(client *ProviderClient, prereqtok, method, url string, options *RequestOpts) (*http.Response, error) { - err := client.Reauthenticate(prereqtok) - if err != nil { - message := fmt.Sprintf(CEReauthFuncErrorMessage, err.Error()) - return nil, NewSystemCommonError(CEReauthFuncErrorCode, message) - } - if options.RawBody != nil { - if seeker, ok := options.RawBody.(io.Seeker); ok { - seeker.Seek(0, 0) - } - } - resp, err := client.Request(method, url, options) - if err != nil { - return nil, err - } - - return resp, nil -} - -func isTimeout(err error) bool { - if err == nil { - return true - } - netErr, isNetError := err.(net.Error) - return isNetError && netErr.Timeout() -} - -func isServerError(httpResponse *http.Response) bool { - return httpResponse.StatusCode >= http.StatusInternalServerError -} - -func defaultOkCodes(method string) []int { - switch { - case method == "GET": - return []int{200} - case method == "POST": - return []int{201, 202} - case method == "PUT": - return []int{201, 202} - case method == "PATCH": - return []int{200, 204} - case method == "DELETE": - return []int{202, 204} - } - - return []int{} -} - -// UserAgent represents a User-Agent header. -type UserAgent struct { - // prepend is the slice of User-Agent strings to prepend to DefaultUserAgent. - // All the strings to prepend are accumulated and prepended in the Join method. - prepend []string -} - -// Prepend prepends a user-defined string to the default User-Agent string. Users -// may pass in one or more strings to prepend. -func (ua *UserAgent) Prepend(s ...string) { - ua.prepend = append(s, ua.prepend...) -} - -// Join concatenates all the user-defined User-Agend strings with the default -// Gophercloud User-Agent string. -func (ua *UserAgent) Join() string { - uaSlice := append(ua.prepend, DefaultUserAgent) - return strings.Join(uaSlice, " ") -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/results.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/results.go deleted file mode 100644 index 128a8d857125..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/results.go +++ /dev/null @@ -1,409 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "reflect" - "strconv" - "time" -) - -/* -Result is an internal type to be used by individual resource packages, but its -methods will be available on a wide variety of user-facing embedding types. - -It acts as a base struct that other Result types, returned from request -functions, can embed for convenience. All Results capture basic information -from the HTTP transaction that was performed, including the response body, -HTTP headers, and any errors that happened. - -Generally, each Result type will have an Extract method that can be used to -further interpret the result's payload in a specific context. Extensions or -providers can then provide additional extraction functions to pull out -provider- or extension-specific information as well. -*/ -type Result struct { - // Body is the payload of the HTTP response from the server. In most cases, - // this will be the deserialized JSON structure. - Body interface{} - - // Header contains the HTTP header structure from the original response. - Header http.Header - - // Err is an error that occurred during the operation. It's deferred until - // extraction to make it easier to chain the Extract call. - Err error -} - -// ExtractInto allows users to provide an object into which `Extract` will extract -// the `Result.Body`. This would be useful for OpenStack providers that have -// different fields in the response object than OpenStack proper. -func (r Result) ExtractInto(to interface{}) error { - if r.Err != nil { - return r.Err - } - - if reader, ok := r.Body.(io.Reader); ok { - if readCloser, ok := reader.(io.Closer); ok { - defer readCloser.Close() - } - return json.NewDecoder(reader).Decode(to) - } - - b, err := json.Marshal(r.Body) - if err != nil { - return err - } - err = json.Unmarshal(b, to) - - return err -} - -func (r Result) extractIntoPtr(to interface{}, label string) error { - if label == "" { - return r.ExtractInto(&to) - } - - var m map[string]interface{} - err := r.ExtractInto(&m) - if err != nil { - return err - } - - b, err := json.Marshal(m[label]) - if err != nil { - return err - } - - toValue := reflect.ValueOf(to) - if toValue.Kind() == reflect.Ptr { - toValue = toValue.Elem() - } - - switch toValue.Kind() { - case reflect.Slice: - typeOfV := toValue.Type().Elem() - if typeOfV.Kind() == reflect.Struct { - if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { - newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0) - newType := reflect.New(typeOfV).Elem() - - for _, v := range m[label].([]interface{}) { - b, err := json.Marshal(v) - if err != nil { - return err - } - - for i := 0; i < newType.NumField(); i++ { - s := newType.Field(i).Addr().Interface() - err = json.NewDecoder(bytes.NewReader(b)).Decode(s) - if err != nil { - return err - } - } - newSlice = reflect.Append(newSlice, newType) - } - toValue.Set(newSlice) - } - } - case reflect.Struct: - typeOfV := toValue.Type() - if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { - for i := 0; i < toValue.NumField(); i++ { - toField := toValue.Field(i) - if toField.Kind() == reflect.Struct { - s := toField.Addr().Interface() - err = json.NewDecoder(bytes.NewReader(b)).Decode(s) - if err != nil { - return err - } - } - } - } - } - - err = json.Unmarshal(b, &to) - return err -} - -// ExtractIntoStructPtr will unmarshal the Result (r) into the provided -// interface{} (to). -// -// NOTE: For internal use only -// -// `to` must be a pointer to an underlying struct type -// -// If provided, `label` will be filtered out of the response -// body prior to `r` being unmarshalled into `to`. -func (r Result) ExtractIntoStructPtr(to interface{}, label string) error { - if r.Err != nil { - return r.Err - } - - t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("Expected pointer, got %v", k) - } - switch t.Elem().Kind() { - case reflect.Struct: - return r.extractIntoPtr(to, label) - default: - return fmt.Errorf("Expected pointer to struct, got: %v", t) - } -} - -// ExtractIntoSlicePtr will unmarshal the Result (r) into the provided -// interface{} (to). -// -// NOTE: For internal use only -// -// `to` must be a pointer to an underlying slice type -// -// If provided, `label` will be filtered out of the response -// body prior to `r` being unmarshalled into `to`. -func (r Result) ExtractIntoSlicePtr(to interface{}, label string) error { - if r.Err != nil { - return r.Err - } - - t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("Expected pointer, got %v", k) - } - switch t.Elem().Kind() { - case reflect.Slice: - return r.extractIntoPtr(to, label) - default: - return fmt.Errorf("Expected pointer to slice, got: %v", t) - } -} - -// PrettyPrintJSON creates a string containing the full response body as -// pretty-printed JSON. It's useful for capturing test fixtures and for -// debugging extraction bugs. If you include its output in an issue related to -// a buggy extraction function, we will all love you forever. -func (r Result) PrettyPrintJSON() string { - pretty, err := json.MarshalIndent(r.Body, "", " ") - if err != nil { - panic(err.Error()) - } - return string(pretty) -} - -// ErrResult is an internal type to be used by individual resource packages, but -// its methods will be available on a wide variety of user-facing embedding -// types. -// -// It represents results that only contain a potential error and -// nothing else. Usually, if the operation executed successfully, the Err field -// will be nil; otherwise it will be stocked with a relevant error. Use the -// ExtractErr method -// to cleanly pull it out. -type ErrResult struct { - Result -} - -// ExtractErr is a function that extracts error information, or nil, from a result. -func (r ErrResult) ExtractErr() error { - return r.Err -} - -/* -HeaderResult is an internal type to be used by individual resource packages, but -its methods will be available on a wide variety of user-facing embedding types. - -It represents a result that only contains an error (possibly nil) and an -http.Header. This is used, for example, by the objectstorage packages in -openstack, because most of the operations don't return response bodies, but do -have relevant information in headers. -*/ -type HeaderResult struct { - Result -} - -// ExtractInto allows users to provide an object into which `Extract` will -// extract the http.Header headers of the result. -func (r HeaderResult) ExtractInto(to interface{}) error { - if r.Err != nil { - return r.Err - } - - tmpHeaderMap := map[string]string{} - for k, v := range r.Header { - if len(v) > 0 { - tmpHeaderMap[k] = v[0] - } - } - - b, err := json.Marshal(tmpHeaderMap) - if err != nil { - return err - } - err = json.Unmarshal(b, to) - - return err -} - -// RFC3339Milli describes a common time format used by some API responses. -const RFC3339Milli = "2006-01-02T15:04:05.999999Z" - -// JSONRFC3339Milli ... -type JSONRFC3339Milli time.Time - -// UnmarshalJSON ... -func (jt *JSONRFC3339Milli) UnmarshalJSON(data []byte) error { - b := bytes.NewBuffer(data) - dec := json.NewDecoder(b) - var s string - if err := dec.Decode(&s); err != nil { - return err - } - t, err := time.Parse(RFC3339Milli, s) - if err != nil { - return err - } - *jt = JSONRFC3339Milli(t) - return nil -} - -// RFC3339MilliNoZ ... -const RFC3339MilliNoZ = "2006-01-02T15:04:05.999999" - -// JSONRFC3339MilliNoZ ... -type JSONRFC3339MilliNoZ time.Time - -// UnmarshalJSON ... -func (jt *JSONRFC3339MilliNoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339MilliNoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339MilliNoZ(t) - return nil -} - -// JSONRFC1123 ... -type JSONRFC1123 time.Time - -// UnmarshalJSON ... -func (jt *JSONRFC1123) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(time.RFC1123, s) - if err != nil { - return err - } - *jt = JSONRFC1123(t) - return nil -} - -// JSONUnix ... -type JSONUnix time.Time - -// UnmarshalJSON ... -func (jt *JSONUnix) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - unix, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return err - } - t = time.Unix(unix, 0) - *jt = JSONUnix(t) - return nil -} - -// RFC3339NoZ is the time format used in Heat (Orchestration). -const RFC3339NoZ = "2006-01-02T15:04:05" - -// JSONRFC3339NoZ ... -type JSONRFC3339NoZ time.Time - -// UnmarshalJSON ... -func (jt *JSONRFC3339NoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339NoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339NoZ(t) - return nil -} - -/* -Link is an internal type to be used in packages of collection resources that are -paginated in a certain way. - -It's a response substructure common to many paginated collection results that is -used to point to related pages. Usually, the one we care about is the one with -Rel field set to "next". -*/ -type Link struct { - Href string `json:"href"` - Rel string `json:"rel"` -} - -/* -ExtractNextURL is an internal function useful for packages of collection -resources that are paginated in a certain way. - -It attempts to extract the "next" URL from slice of Link structs, or -"" if no such URL is present. -*/ -func ExtractNextURL(links []Link) (string, error) { - var url string - - for _, l := range links { - if l.Rel == "next" { - url = l.Href - } - } - - if url == "" { - return "", nil - } - - return url, nil -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/service_client.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/service_client.go deleted file mode 100644 index 3602e90738f7..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/service_client.go +++ /dev/null @@ -1,212 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "io" - "net/http" - "strings" - "sync" -) - -// ServiceClient stores details required to interact with a specific service API implemented by a provider. -// Generally, you'll acquire these by calling the appropriate `New` method on a ProviderClient. -type ServiceClient struct { - // ProviderClient is a reference to the provider that implements this service. - *ProviderClient - - // Endpoint is the base URL of the service's API, acquired from a service catalog. - // It MUST end with a /. - Endpoint string - - // ResourceBase is the base URL shared by the resources within a service's API. It should include - // the API version and, like Endpoint, MUST end with a / if set. If not set, the Endpoint is used - // as-is, instead. - ResourceBase string - - // This is the service client type (e.g. compute, sharev2). - // NOTE: FOR INTERNAL USE ONLY. DO NOT SET. GOPHERCLOUD WILL SET THIS. - // It is only exported because it gets set in a different package. - Type string - - // The microversion of the service to use. Set this to use a particular microversion. - Microversion string - - // lock,The service needs to be locked when setting the micro version. - lock sync.Mutex - - // MoreHeaders allows users (or Gophercloud) to set service-wide headers on requests. Put another way, - // values set in this field will be set on all the HTTP requests the service client sends. - MoreHeaders map[string]string - - HandleError func(httpStatus int, responseContent string) error -} - -// SetMicroversion Set the service micro version field. -func (client *ServiceClient) SetMicroversion(microversion string) { - client.lock.Lock() - client.Microversion = microversion - client.lock.Unlock() - return -} - -// UnsetMicroversion Unset the service micro version field. -func (client *ServiceClient) UnsetMicroversion() { - client.lock.Lock() - client.Microversion = "" - client.lock.Unlock() - return -} - -// ResourceBaseURL returns the base URL of any resources used by this service. It MUST end with a /. -func (client *ServiceClient) ResourceBaseURL() string { - if client.ResourceBase != "" { - return client.ResourceBase - } - return client.Endpoint -} - -// ServiceURL constructs a URL for a resource belonging to this provider. -func (client *ServiceClient) ServiceURL(parts ...string) string { - return client.ResourceBaseURL() + strings.Join(parts, "/") -} - -func (client *ServiceClient) initReqOpts(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) { - if v, ok := (JSONBody).(io.Reader); ok { - opts.RawBody = v - } else if JSONBody != nil { - opts.JSONBody = JSONBody - } - - if JSONResponse != nil { - opts.JSONResponse = JSONResponse - } - - if opts.MoreHeaders == nil { - opts.MoreHeaders = make(map[string]string) - } - - if client.Microversion != "" { - client.setMicroversionHeader(opts) - } - - if &client.ProviderClient.AKSKOptions != nil { - if client.ProviderClient.AKSKOptions.SecurityToken != "" { - opts.MoreHeaders["X-Security-Token"] = client.ProviderClient.AKSKOptions.SecurityToken - } - if client.ProviderClient.AKSKOptions.ProjectID != "" { - opts.MoreHeaders["X-Project-Id"] = client.ProjectID - } else if client.ProviderClient.AKSKOptions.DomainID != "" { - opts.MoreHeaders["X-Domain-Id"] = client.DomainID - } - } -} - -// Get calls `Request` with the "GET" HTTP verb. -func (client *ServiceClient) Get(url string, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, nil, JSONResponse, opts) - return client.Request("GET", url, opts) -} - -// Post calls `Request` with the "POST" HTTP verb. -func (client *ServiceClient) Post(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, JSONBody, JSONResponse, opts) - return client.Request("POST", url, opts) -} - -// Put calls `Request` with the "PUT" HTTP verb. -func (client *ServiceClient) Put(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, JSONBody, JSONResponse, opts) - return client.Request("PUT", url, opts) -} - -// Patch calls `Request` with the "PATCH" HTTP verb. -func (client *ServiceClient) Patch(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, JSONBody, JSONResponse, opts) - return client.Request("PATCH", url, opts) -} - -// Delete calls `Request` with the "DELETE" HTTP verb. -func (client *ServiceClient) Delete(url string, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, nil, nil, opts) - return client.Request("DELETE", url, opts) -} - -// Head calls `Request` with the "HEAD" HTTP verb. -func (client *ServiceClient) Head(url string, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, nil, nil, opts) - return client.Request("HEAD", url, opts) -} - -func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { - - switch client.Type { - case "compute": - - if client.Microversion <= "2.26" { - opts.MoreHeaders["X-OpenStack-Nova-API-Version"] = client.Microversion - } else { - opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion - } - //case "sharev2": - // opts.MoreHeaders["X-OpenStack-Manila-API-Version"] = client.Microversion - //case "volume": - // opts.MoreHeaders["X-OpenStack-Volume-API-Version"] = client.Microversion - } - // - //if client.Type != "" { - // opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion - //} -} - -// Request carries out the HTTP operation for the service client -func (client *ServiceClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { - if len(client.MoreHeaders) > 0 { - if options == nil { - options = new(RequestOpts) - } - for k, v := range client.MoreHeaders { - options.MoreHeaders[k] = v - //if _, ok := options.MoreHeaders[k]; !ok { - //options.MoreHeaders[k] = v - //} - } - } - - if client.HandleError != nil { - options.HandleError = client.HandleError - } - return client.ProviderClient.Request(method, url, options) -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/testhelper/fake_server.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/testhelper/fake_server.go deleted file mode 100644 index 995292037f50..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/testhelper/fake_server.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 testhelper - -import ( - "net/http" - "net/http/httptest" -) - -var ( - // Mux points to http.ServeMux - Mux *http.ServeMux - // Server points to httptest.Server - Server *httptest.Server -) - -// CreateServer creates the fake server -func CreateServer() { - Mux = http.NewServeMux() - Server = httptest.NewServer(Mux) -} - -// ShutDownServer closes the fake server -func ShutDownServer() { - Server.Close() -} - -// GetEndpoint gets the endpoint of the fake server -func GetEndpoint() string { - return Server.URL -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/util.go b/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/util.go deleted file mode 100644 index 4c1fb81829b0..000000000000 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/util.go +++ /dev/null @@ -1,200 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -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 huaweicloudsdk - -import ( - "fmt" - "net/url" - "path" - "path/filepath" - "reflect" - "runtime" - "strconv" - "strings" - "time" -) - -// WaitFor polls a predicate function, once per second, up to a timeout limit. -// This is useful to wait for a resource to transition to a certain state. -// To handle situations when the predicate might hang indefinitely, the -// predicate will be prematurely cancelled after the timeout. -// Resource packages will wrap this in a more convenient function that's -// specific to a certain resource, but it can also be useful on its own. -func WaitFor(timeout int, predicate func() (bool, error)) error { - type WaitForResult struct { - Success bool - Error error - } - - start := time.Now().Unix() - - for { - // If a timeout is set, and that's been exceeded, shut it down. - if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) { - return fmt.Errorf("A timeout occurred") - } - - time.Sleep(1 * time.Second) - - var result WaitForResult - ch := make(chan bool, 1) - go func() { - defer close(ch) - satisfied, err := predicate() - result.Success = satisfied - result.Error = err - }() - - select { - case <-ch: - if result.Error != nil { - return result.Error - } - if result.Success { - return nil - } - // If the predicate has not finished by the timeout, cancel it. - case <-time.After(time.Duration(timeout) * time.Second): - return fmt.Errorf("A timeout occurred") - } - } -} - -// NormalizeURL is an internal function to be used by provider clients. -// -// It ensures that each endpoint URL has a closing `/`, as expected by -// ServiceClient's methods. -func NormalizeURL(url string) string { - if !strings.HasSuffix(url, "/") { - return url + "/" - } - return url -} - -// NormalizePathURL is used to convert rawPath to a fqdn, using basePath as -// a reference in the filesystem, if necessary. basePath is assumed to contain -// either '.' when first used, or the file:// type fqdn of the parent resource. -// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml -func NormalizePathURL(basePath, rawPath string) (string, error) { - u, err := url.Parse(rawPath) - if err != nil { - return "", err - } - // if a scheme is defined, it must be a fqdn already - if u.Scheme != "" { - return u.String(), nil - } - // if basePath is a url, then child resources are assumed to be relative to it - bu, err := url.Parse(basePath) - if err != nil { - return "", err - } - var basePathSys, absPathSys string - if bu.Scheme != "" { - basePathSys = filepath.FromSlash(bu.Path) - absPathSys = filepath.Join(basePathSys, rawPath) - bu.Path = filepath.ToSlash(absPathSys) - return bu.String(), nil - } - - absPathSys = filepath.Join(basePath, rawPath) - u.Path = filepath.ToSlash(absPathSys) - if err != nil { - return "", err - } - u.Scheme = "file" - return u.String(), nil - -} - -// InitStructWithDefaultTag Initialize the structure instance using the structure tag. -func InitStructWithDefaultTag(bean interface{}) { - configType := reflect.TypeOf(bean) - for i := 0; i < configType.Elem().NumField(); i++ { - field := configType.Elem().Field(i) - defaultValue := field.Tag.Get("default") - if defaultValue == "" { - continue - } - setter := reflect.ValueOf(bean).Elem().Field(i) - switch field.Type.String() { - case "int": - intValue, _ := strconv.ParseInt(defaultValue, 10, 64) - setter.SetInt(intValue) - case "time.Duration": - intValue, _ := strconv.ParseInt(defaultValue, 10, 64) - setter.SetInt(intValue) - case "string": - setter.SetString(defaultValue) - case "bool": - boolValue, _ := strconv.ParseBool(defaultValue) - setter.SetBool(boolValue) - } - } -} - -// IsInStrSlice Determine if the string is in the array. -func IsInStrSlice(sliceStr []string, s string) bool { - for _, v := range sliceStr { - if v == s { - return true - } - } - return false -} - -// EnableDebug SDK log switch defaults value is false. -var EnableDebug bool - -// Logger define the logger struct. -type Logger struct { - DebugEnable bool `default:"false"` -} - -// Debug Format the log information and print the information to the console. -func (log *Logger) Debug(format string, v ...interface{}) { - if log.DebugEnable { - msg := fmt.Sprintf("[DEBUG] "+format, v...) - writeMsg(msg) - } -} - -func writeMsg(msg string) { - _, file, line, ok := runtime.Caller(2) - if !ok { - file = "???" - line = 0 - } - _, filename := path.Split(file) - msg = fmt.Sprintf("[%s:%s] %s", filename, strconv.FormatInt(int64(line), 10), msg) - - printMsg(msg) -} - -//printMsg -func printMsg(msg string) { - when := time.Now().Format("2006-01-02 15:04:05") - buf := []byte(fmt.Sprintf("[%s] ", when)) - fmt.Println(string(append(append(buf, msg...)))) -} - -// GetLogger Return log initialization structure instance. -func GetLogger() *Logger { - log := new(Logger) - log.DebugEnable = EnableDebug - return log -} diff --git a/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_cloud_config.go b/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_cloud_config.go index 3ddff4ec2aba..67f50b6d6ffa 100644 --- a/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_cloud_config.go +++ b/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud_cloud_config.go @@ -26,22 +26,16 @@ import ( huaweicloudsdkconfig "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/core/config" huaweicloudsdkas "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/services/as/v1" huaweicloudsdkecs "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huaweicloud-sdk-go-v3/services/ecs/v2" - - "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/huaweicloud/huawei-cloud-sdk-go/auth/aksk" ) // CloudConfig is the cloud config file for huaweicloud. type CloudConfig struct { Global struct { - IdentityEndpoint string `gcfg:"identity-endpoint"` // example: "https://iam.cn-north-4.myhuaweicloud.com/v3.0" - ECSEndpoint string `gcfg:"ecs-endpoint"` - ASEndpoint string `gcfg:"as-endpoint"` - ProjectID string `gcfg:"project-id"` - AccessKey string `gcfg:"access-key"` - SecretKey string `gcfg:"secret-key"` - Cloud string `gcfg:"cloud"` // example: "huaweicloud" - Region string `gcfg:"region"` // example: "cn-north-4" - DomainID string `gcfg:"domain-id"` // The ACCOUNT ID. example: "a0e8ff63c0fb4fd49cc2dbdf1dea14e2" + ECSEndpoint string `gcfg:"ecs-endpoint"` + ASEndpoint string `gcfg:"as-endpoint"` + ProjectID string `gcfg:"project-id"` + AccessKey string `gcfg:"access-key"` + SecretKey string `gcfg:"secret-key"` } } @@ -108,20 +102,6 @@ func (c *CloudConfig) validate() error { return nil } -// toAKSKOptions creates and returns a new instance of type aksk.AKSKOptions -func toAKSKOptions(cfg CloudConfig) aksk.AKSKOptions { - opts := aksk.AKSKOptions{ - IdentityEndpoint: cfg.Global.IdentityEndpoint, - ProjectID: cfg.Global.ProjectID, - AccessKey: cfg.Global.AccessKey, - SecretKey: cfg.Global.SecretKey, - Cloud: cfg.Global.Cloud, - Region: cfg.Global.Region, - DomainID: cfg.Global.DomainID, - } - return opts -} - func readConf(confFile string) (*CloudConfig, error) { var conf io.ReadCloser conf, err := os.Open(confFile)