mirror of https://github.com/k3s-io/k3s
Add vendored version of the cloud libraries
parent
83ba05a002
commit
295a797047
|
@ -0,0 +1,202 @@
|
|||
|
||||
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
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
55
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/constants.go
generated
vendored
Normal file
55
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/constants.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NetworkTier represents the Network Service Tier used by a resource
|
||||
type NetworkTier string
|
||||
|
||||
// LbScheme represents the possible types of load balancers
|
||||
type LbScheme string
|
||||
|
||||
const (
|
||||
NetworkTierStandard NetworkTier = "Standard"
|
||||
NetworkTierPremium NetworkTier = "Premium"
|
||||
NetworkTierDefault NetworkTier = NetworkTierPremium
|
||||
|
||||
SchemeExternal LbScheme = "EXTERNAL"
|
||||
SchemeInternal LbScheme = "INTERNAL"
|
||||
)
|
||||
|
||||
// ToGCEValue converts NetworkTier to a string that we can populate the
|
||||
// NetworkTier field of GCE objects, including ForwardingRules and Addresses.
|
||||
func (n NetworkTier) ToGCEValue() string {
|
||||
return strings.ToUpper(string(n))
|
||||
}
|
||||
|
||||
// NetworkTierGCEValueToType converts the value of the NetworkTier field of a
|
||||
// GCE object to the NetworkTier type.
|
||||
func NetworkTierGCEValueToType(s string) NetworkTier {
|
||||
switch s {
|
||||
case NetworkTierStandard.ToGCEValue():
|
||||
return NetworkTierStandard
|
||||
case NetworkTierPremium.ToGCEValue():
|
||||
return NetworkTierPremium
|
||||
default:
|
||||
return NetworkTier(s)
|
||||
}
|
||||
}
|
31
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/context.go
generated
vendored
Normal file
31
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/context.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultCallTimeout = 1 * time.Hour
|
||||
)
|
||||
|
||||
// ContextWithCallTimeout returns a context with a default timeout, used for generated client calls.
|
||||
func ContextWithCallTimeout() (context.Context, context.CancelFunc) {
|
||||
return context.WithTimeout(context.Background(), defaultCallTimeout)
|
||||
}
|
117
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/doc.go
generated
vendored
Normal file
117
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud implements a more golang friendly interface to the GCE compute
|
||||
// API. The code in this package is generated automatically via the generator
|
||||
// implemented in "gen/main.go". The code generator creates the basic CRUD
|
||||
// actions for the given resource: "Insert", "Get", "List" and "Delete".
|
||||
// Additional methods by customizing the ServiceInfo object (see below).
|
||||
// Generated code includes a full mock of the GCE compute API.
|
||||
//
|
||||
// Usage
|
||||
//
|
||||
// The root of the GCE compute API is the interface "Cloud". Code written using
|
||||
// Cloud can be used against the actual implementation "GCE" or "MockGCE".
|
||||
//
|
||||
// func foo(cloud Cloud) {
|
||||
// igs, err := cloud.InstanceGroups().List(ctx, "us-central1-b", filter.None)
|
||||
// ...
|
||||
// }
|
||||
// // Run foo against the actual cloud.
|
||||
// foo(NewGCE(&Service{...}))
|
||||
// // Run foo with a mock.
|
||||
// foo(NewMockGCE())
|
||||
//
|
||||
// Rate limiting and routing
|
||||
//
|
||||
// The generated code allows for custom policies for operation rate limiting
|
||||
// and GCE project routing. See RateLimiter and ProjectRouter for more details.
|
||||
//
|
||||
// Mocks
|
||||
//
|
||||
// Mocks are automatically generated for each type implementing basic logic for
|
||||
// resource manipulation. This eliminates the boilerplate required to mock GCE
|
||||
// functionality. Each method will also have a corresponding "xxxHook"
|
||||
// function generated in the mock structure where unit test code can hook the
|
||||
// execution of the method.
|
||||
//
|
||||
// Mocks for different versions of the same service will share the same set of
|
||||
// objects, i.e. an alpha object will be visible with beta and GA methods.
|
||||
// Note that translation is done with JSON serialization between the API versions.
|
||||
//
|
||||
// Changing service code generation
|
||||
//
|
||||
// The list of services to generate is contained in "meta/meta.go". To add a
|
||||
// service, add an entry to the list "meta.AllServices". An example entry:
|
||||
//
|
||||
// &ServiceInfo{
|
||||
// Object: "InstanceGroup", // Name of the object type.
|
||||
// Service: "InstanceGroups", // Name of the service.
|
||||
// Resource: "instanceGroups", // Lowercase resource name (as appears in the URL).
|
||||
// version: meta.VersionAlpha, // API version (one entry per version is needed).
|
||||
// keyType: Zonal, // What kind of resource this is.
|
||||
// serviceType: reflect.TypeOf(&alpha.InstanceGroupsService{}), // Associated golang type.
|
||||
// additionalMethods: []string{ // Additional methods to generate code for.
|
||||
// "SetNamedPorts",
|
||||
// },
|
||||
// options: <options> // Or'd ("|") together.
|
||||
// }
|
||||
//
|
||||
// Read-only objects
|
||||
//
|
||||
// Services such as Regions and Zones do not allow for mutations. Specify
|
||||
// "ReadOnly" in ServiceInfo.options to omit the mutation methods.
|
||||
//
|
||||
// Adding custom methods
|
||||
//
|
||||
// Some methods that may not be properly handled by the generated code. To enable
|
||||
// addition of custom code to the generated mocks, set the "CustomOps" option
|
||||
// in "meta.ServiceInfo" entry. This will make the generated service interface
|
||||
// embed a "<ServiceName>Ops" interface. This interface MUST be written by hand
|
||||
// and contain the custom method logic. Corresponding methods must be added to
|
||||
// the corresponding Mockxxx and GCExxx struct types.
|
||||
//
|
||||
// // In "meta/meta.go":
|
||||
// &ServiceInfo{
|
||||
// Object: "InstanceGroup",
|
||||
// ...
|
||||
// options: CustomOps,
|
||||
// }
|
||||
//
|
||||
// // In the generated code "gen.go":
|
||||
// type InstanceGroups interface {
|
||||
// InstanceGroupsOps // Added by CustomOps option.
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// // In hand written file:
|
||||
// type InstanceGroupsOps interface {
|
||||
// MyMethod()
|
||||
// }
|
||||
//
|
||||
// func (mock *MockInstanceGroups) MyMethod() {
|
||||
// // Custom mock implementation.
|
||||
// }
|
||||
//
|
||||
// func (gce *GCEInstanceGroups) MyMethod() {
|
||||
// // Custom implementation.
|
||||
// }
|
||||
//
|
||||
// Update generated codes
|
||||
//
|
||||
// Run hack/update-cloudprovider-gce.sh to update the generated codes.
|
||||
//
|
||||
package cloud
|
303
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter/filter.go
generated
vendored
Normal file
303
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter/filter.go
generated
vendored
Normal file
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 filter encapsulates the filter argument to compute API calls.
|
||||
//
|
||||
// // List all global addresses (no filter).
|
||||
// c.GlobalAddresses().List(ctx, filter.None)
|
||||
//
|
||||
// // List global addresses filtering for name matching "abc.*".
|
||||
// c.GlobalAddresses().List(ctx, filter.Regexp("name", "abc.*"))
|
||||
//
|
||||
// // List on multiple conditions.
|
||||
// f := filter.Regexp("name", "homer.*").AndNotRegexp("name", "homers")
|
||||
// c.GlobalAddresses().List(ctx, f)
|
||||
package filter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
var (
|
||||
// None indicates that the List result set should not be filter (i.e.
|
||||
// return all values).
|
||||
None *F
|
||||
)
|
||||
|
||||
// Regexp returns a filter for fieldName matches regexp v.
|
||||
func Regexp(fieldName, v string) *F {
|
||||
return (&F{}).AndRegexp(fieldName, v)
|
||||
}
|
||||
|
||||
// NotRegexp returns a filter for fieldName not matches regexp v.
|
||||
func NotRegexp(fieldName, v string) *F {
|
||||
return (&F{}).AndNotRegexp(fieldName, v)
|
||||
}
|
||||
|
||||
// EqualInt returns a filter for fieldName ~ v.
|
||||
func EqualInt(fieldName string, v int) *F {
|
||||
return (&F{}).AndEqualInt(fieldName, v)
|
||||
}
|
||||
|
||||
// NotEqualInt returns a filter for fieldName != v.
|
||||
func NotEqualInt(fieldName string, v int) *F {
|
||||
return (&F{}).AndNotEqualInt(fieldName, v)
|
||||
}
|
||||
|
||||
// EqualBool returns a filter for fieldName == v.
|
||||
func EqualBool(fieldName string, v bool) *F {
|
||||
return (&F{}).AndEqualBool(fieldName, v)
|
||||
}
|
||||
|
||||
// NotEqualBool returns a filter for fieldName != v.
|
||||
func NotEqualBool(fieldName string, v bool) *F {
|
||||
return (&F{}).AndNotEqualBool(fieldName, v)
|
||||
}
|
||||
|
||||
// F is a filter to be used with List() operations.
|
||||
//
|
||||
// From the compute API description:
|
||||
//
|
||||
// Sets a filter {expression} for filtering listed resources. Your {expression}
|
||||
// must be in the format: field_name comparison_string literal_string.
|
||||
//
|
||||
// The field_name is the name of the field you want to compare. Only atomic field
|
||||
// types are supported (string, number, boolean). The comparison_string must be
|
||||
// either eq (equals) or ne (not equals). The literal_string is the string value
|
||||
// to filter to. The literal value must be valid for the type of field you are
|
||||
// filtering by (string, number, boolean). For string fields, the literal value is
|
||||
// interpreted as a regular expression using RE2 syntax. The literal value must
|
||||
// match the entire field.
|
||||
//
|
||||
// For example, to filter for instances that do not have a name of
|
||||
// example-instance, you would use name ne example-instance.
|
||||
//
|
||||
// You can filter on nested fields. For example, you could filter on instances
|
||||
// that have set the scheduling.automaticRestart field to true. Use filtering on
|
||||
// nested fields to take advantage of labels to organize and search for results
|
||||
// based on label values.
|
||||
//
|
||||
// To filter on multiple expressions, provide each separate expression within
|
||||
// parentheses. For example, (scheduling.automaticRestart eq true)
|
||||
// (zone eq us-central1-f). Multiple expressions are treated as AND expressions,
|
||||
// meaning that resources must match all expressions to pass the filters.
|
||||
type F struct {
|
||||
predicates []filterPredicate
|
||||
}
|
||||
|
||||
// And joins two filters together.
|
||||
func (fl *F) And(rest *F) *F {
|
||||
fl.predicates = append(fl.predicates, rest.predicates...)
|
||||
return fl
|
||||
}
|
||||
|
||||
// AndRegexp adds a field match string predicate.
|
||||
func (fl *F) AndRegexp(fieldName, v string) *F {
|
||||
fl.predicates = append(fl.predicates, filterPredicate{fieldName: fieldName, op: equals, s: &v})
|
||||
return fl
|
||||
}
|
||||
|
||||
// AndNotRegexp adds a field not match string predicate.
|
||||
func (fl *F) AndNotRegexp(fieldName, v string) *F {
|
||||
fl.predicates = append(fl.predicates, filterPredicate{fieldName: fieldName, op: notEquals, s: &v})
|
||||
return fl
|
||||
}
|
||||
|
||||
// AndEqualInt adds a field == int predicate.
|
||||
func (fl *F) AndEqualInt(fieldName string, v int) *F {
|
||||
fl.predicates = append(fl.predicates, filterPredicate{fieldName: fieldName, op: equals, i: &v})
|
||||
return fl
|
||||
}
|
||||
|
||||
// AndNotEqualInt adds a field != int predicate.
|
||||
func (fl *F) AndNotEqualInt(fieldName string, v int) *F {
|
||||
fl.predicates = append(fl.predicates, filterPredicate{fieldName: fieldName, op: notEquals, i: &v})
|
||||
return fl
|
||||
}
|
||||
|
||||
// AndEqualBool adds a field == bool predicate.
|
||||
func (fl *F) AndEqualBool(fieldName string, v bool) *F {
|
||||
fl.predicates = append(fl.predicates, filterPredicate{fieldName: fieldName, op: equals, b: &v})
|
||||
return fl
|
||||
}
|
||||
|
||||
// AndNotEqualBool adds a field != bool predicate.
|
||||
func (fl *F) AndNotEqualBool(fieldName string, v bool) *F {
|
||||
fl.predicates = append(fl.predicates, filterPredicate{fieldName: fieldName, op: notEquals, b: &v})
|
||||
return fl
|
||||
}
|
||||
|
||||
func (fl *F) String() string {
|
||||
if len(fl.predicates) == 1 {
|
||||
return fl.predicates[0].String()
|
||||
}
|
||||
|
||||
var pl []string
|
||||
for _, p := range fl.predicates {
|
||||
pl = append(pl, "("+p.String()+")")
|
||||
}
|
||||
return strings.Join(pl, " ")
|
||||
}
|
||||
|
||||
// Match returns true if the F as specifies matches the given object. This
|
||||
// is used by the Mock implementations to perform filtering and SHOULD NOT be
|
||||
// used in production code as it is not well-tested to be equivalent to the
|
||||
// actual compute API.
|
||||
func (fl *F) Match(obj interface{}) bool {
|
||||
if fl == nil {
|
||||
return true
|
||||
}
|
||||
for _, p := range fl.predicates {
|
||||
if !p.match(obj) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type filterOp int
|
||||
|
||||
const (
|
||||
equals filterOp = iota
|
||||
notEquals filterOp = iota
|
||||
)
|
||||
|
||||
// filterPredicate is an individual predicate for a fieldName and value.
|
||||
type filterPredicate struct {
|
||||
fieldName string
|
||||
|
||||
op filterOp
|
||||
s *string
|
||||
i *int
|
||||
b *bool
|
||||
}
|
||||
|
||||
func (fp *filterPredicate) String() string {
|
||||
var op string
|
||||
switch fp.op {
|
||||
case equals:
|
||||
op = "eq"
|
||||
case notEquals:
|
||||
op = "ne"
|
||||
default:
|
||||
op = "invalidOp"
|
||||
}
|
||||
|
||||
var value string
|
||||
switch {
|
||||
case fp.s != nil:
|
||||
// There does not seem to be any sort of escaping as specified in the
|
||||
// document. This means it's possible to create malformed expressions.
|
||||
value = *fp.s
|
||||
case fp.i != nil:
|
||||
value = fmt.Sprintf("%d", *fp.i)
|
||||
case fp.b != nil:
|
||||
value = fmt.Sprintf("%t", *fp.b)
|
||||
default:
|
||||
value = "invalidValue"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s %s", fp.fieldName, op, value)
|
||||
}
|
||||
|
||||
func (fp *filterPredicate) match(o interface{}) bool {
|
||||
v, err := extractValue(fp.fieldName, o)
|
||||
klog.V(6).Infof("extractValue(%q, %#v) = %v, %v", fp.fieldName, o, v, err)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var match bool
|
||||
switch x := v.(type) {
|
||||
case string:
|
||||
if fp.s == nil {
|
||||
return false
|
||||
}
|
||||
re, err := regexp.Compile(*fp.s)
|
||||
if err != nil {
|
||||
klog.Errorf("Match regexp %q is invalid: %v", *fp.s, err)
|
||||
return false
|
||||
}
|
||||
match = re.Match([]byte(x))
|
||||
case int:
|
||||
if fp.i == nil {
|
||||
return false
|
||||
}
|
||||
match = x == *fp.i
|
||||
case bool:
|
||||
if fp.b == nil {
|
||||
return false
|
||||
}
|
||||
match = x == *fp.b
|
||||
}
|
||||
|
||||
switch fp.op {
|
||||
case equals:
|
||||
return match
|
||||
case notEquals:
|
||||
return !match
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// snakeToCamelCase converts from "names_like_this" to "NamesLikeThis" to
|
||||
// interoperate between proto and Golang naming conventions.
|
||||
func snakeToCamelCase(s string) string {
|
||||
parts := strings.Split(s, "_")
|
||||
var ret string
|
||||
for _, x := range parts {
|
||||
ret += strings.Title(x)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// extractValue returns the value of the field named by path in object o if it exists.
|
||||
func extractValue(path string, o interface{}) (interface{}, error) {
|
||||
parts := strings.Split(path, ".")
|
||||
for _, f := range parts {
|
||||
v := reflect.ValueOf(o)
|
||||
// Dereference Ptr to handle *struct.
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return nil, errors.New("field is nil")
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("cannot get field from non-struct (%T)", o)
|
||||
}
|
||||
v = v.FieldByName(snakeToCamelCase(f))
|
||||
if !v.IsValid() {
|
||||
return nil, fmt.Errorf("cannot get field %q as it is not a valid field in %T", f, o)
|
||||
}
|
||||
if !v.CanInterface() {
|
||||
return nil, fmt.Errorf("cannot get field %q in obj of type %T", f, o)
|
||||
}
|
||||
o = v.Interface()
|
||||
}
|
||||
switch o.(type) {
|
||||
case string, int, bool:
|
||||
return o, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unhandled object of type %T", o)
|
||||
}
|
99
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/gce_projects.go
generated
vendored
Normal file
99
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/gce_projects.go
generated
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
// ProjectsOps is the manually implemented methods for the Projects service.
|
||||
type ProjectsOps interface {
|
||||
Get(ctx context.Context, projectID string) (*compute.Project, error)
|
||||
SetCommonInstanceMetadata(ctx context.Context, projectID string, m *compute.Metadata) error
|
||||
}
|
||||
|
||||
// MockProjectOpsState is stored in the mock.X field.
|
||||
type MockProjectOpsState struct {
|
||||
metadata map[string]*compute.Metadata
|
||||
}
|
||||
|
||||
// Get a project by projectID.
|
||||
func (m *MockProjects) Get(ctx context.Context, projectID string) (*compute.Project, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
if p, ok := m.Objects[*meta.GlobalKey(projectID)]; ok {
|
||||
return p.ToGA(), nil
|
||||
}
|
||||
return nil, &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("MockProjects %v not found", projectID),
|
||||
}
|
||||
}
|
||||
|
||||
// Get a project by projectID.
|
||||
func (g *GCEProjects) Get(ctx context.Context, projectID string) (*compute.Project, error) {
|
||||
rk := &RateLimitKey{
|
||||
ProjectID: projectID,
|
||||
Operation: "Get",
|
||||
Version: meta.Version("ga"),
|
||||
Service: "Projects",
|
||||
}
|
||||
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
call := g.s.GA.Projects.Get(projectID)
|
||||
call.Context(ctx)
|
||||
return call.Do()
|
||||
}
|
||||
|
||||
// SetCommonInstanceMetadata for a given project.
|
||||
func (m *MockProjects) SetCommonInstanceMetadata(ctx context.Context, projectID string, meta *compute.Metadata) error {
|
||||
if m.X == nil {
|
||||
m.X = &MockProjectOpsState{metadata: map[string]*compute.Metadata{}}
|
||||
}
|
||||
state := m.X.(*MockProjectOpsState)
|
||||
state.metadata[projectID] = meta
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetCommonInstanceMetadata for a given project.
|
||||
func (g *GCEProjects) SetCommonInstanceMetadata(ctx context.Context, projectID string, m *compute.Metadata) error {
|
||||
rk := &RateLimitKey{
|
||||
ProjectID: projectID,
|
||||
Operation: "SetCommonInstanceMetadata",
|
||||
Version: meta.Version("ga"),
|
||||
Service: "Projects",
|
||||
}
|
||||
if err := g.s.RateLimiter.Accept(ctx, rk); err != nil {
|
||||
return err
|
||||
}
|
||||
call := g.s.GA.Projects.SetCommonInstanceMetadata(projectID, m)
|
||||
call.Context(ctx)
|
||||
|
||||
op, err := call.Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return g.s.WaitForCompletion(ctx, op)
|
||||
}
|
15129
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/gen.go
generated
vendored
Normal file
15129
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/gen.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/doc.go
generated
vendored
Normal file
19
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 meta contains the meta description of the GCE cloud types to
|
||||
// generate code for.
|
||||
package meta
|
108
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/key.go
generated
vendored
Normal file
108
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/key.go
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Key for a GCP resource.
|
||||
type Key struct {
|
||||
Name string
|
||||
Zone string
|
||||
Region string
|
||||
}
|
||||
|
||||
// KeyType is the type of the key.
|
||||
type KeyType string
|
||||
|
||||
const (
|
||||
// Zonal key type.
|
||||
Zonal = "zonal"
|
||||
// Regional key type.
|
||||
Regional = "regional"
|
||||
// Global key type.
|
||||
Global = "global"
|
||||
)
|
||||
|
||||
var (
|
||||
// locationRegexp is the format of regions/zone names in GCE.
|
||||
locationRegexp = regexp.MustCompile("^[a-z](?:[-a-z0-9]+)?$")
|
||||
)
|
||||
|
||||
// ZonalKey returns the key for a zonal resource.
|
||||
func ZonalKey(name, zone string) *Key {
|
||||
return &Key{name, zone, ""}
|
||||
}
|
||||
|
||||
// RegionalKey returns the key for a regional resource.
|
||||
func RegionalKey(name, region string) *Key {
|
||||
return &Key{name, "", region}
|
||||
}
|
||||
|
||||
// GlobalKey returns the key for a global resource.
|
||||
func GlobalKey(name string) *Key {
|
||||
return &Key{name, "", ""}
|
||||
}
|
||||
|
||||
// Type returns the type of the key.
|
||||
func (k *Key) Type() KeyType {
|
||||
switch {
|
||||
case k.Zone != "":
|
||||
return Zonal
|
||||
case k.Region != "":
|
||||
return Regional
|
||||
default:
|
||||
return Global
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a string representation of the key.
|
||||
func (k Key) String() string {
|
||||
switch k.Type() {
|
||||
case Zonal:
|
||||
return fmt.Sprintf("Key{%q, zone: %q}", k.Name, k.Zone)
|
||||
case Regional:
|
||||
return fmt.Sprintf("Key{%q, region: %q}", k.Name, k.Region)
|
||||
default:
|
||||
return fmt.Sprintf("Key{%q}", k.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Valid is true if the key is valid.
|
||||
func (k *Key) Valid() bool {
|
||||
if k.Zone != "" && k.Region != "" {
|
||||
return false
|
||||
}
|
||||
switch {
|
||||
case k.Region != "":
|
||||
return locationRegexp.Match([]byte(k.Region))
|
||||
case k.Zone != "":
|
||||
return locationRegexp.Match([]byte(k.Zone))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// KeysToMap creates a map[Key]bool from a list of keys.
|
||||
func KeysToMap(keys ...Key) map[Key]bool {
|
||||
ret := map[Key]bool{}
|
||||
for _, k := range keys {
|
||||
ret[k] = true
|
||||
}
|
||||
return ret
|
||||
}
|
440
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/meta.go
generated
vendored
Normal file
440
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/meta.go
generated
vendored
Normal file
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 meta
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
alpha "google.golang.org/api/compute/v0.alpha"
|
||||
beta "google.golang.org/api/compute/v0.beta"
|
||||
ga "google.golang.org/api/compute/v1"
|
||||
)
|
||||
|
||||
// Version of the API (ga, alpha, beta).
|
||||
type Version string
|
||||
|
||||
const (
|
||||
// NoGet prevents the Get() method from being generated.
|
||||
NoGet = 1 << iota
|
||||
// NoList prevents the List() method from being generated.
|
||||
NoList = 1 << iota
|
||||
// NoDelete prevents the Delete() method from being generated.
|
||||
NoDelete = 1 << iota
|
||||
// NoInsert prevents the Insert() method from being generated.
|
||||
NoInsert = 1 << iota
|
||||
// CustomOps specifies that an empty interface xxxOps will be generated to
|
||||
// enable custom method calls to be attached to the generated service
|
||||
// interface.
|
||||
CustomOps = 1 << iota
|
||||
// AggregatedList will generated a method for AggregatedList().
|
||||
AggregatedList = 1 << iota
|
||||
|
||||
// ReadOnly specifies that the given resource is read-only and should not
|
||||
// have insert() or delete() methods generated for the wrapper.
|
||||
ReadOnly = NoDelete | NoInsert
|
||||
|
||||
// VersionGA is the API version in compute.v1.
|
||||
VersionGA Version = "ga"
|
||||
// VersionAlpha is the API version in computer.v0.alpha.
|
||||
VersionAlpha Version = "alpha"
|
||||
// VersionBeta is the API version in computer.v0.beta.
|
||||
VersionBeta Version = "beta"
|
||||
)
|
||||
|
||||
// AllVersions is a list of all versions of the GCE API.
|
||||
var AllVersions = []Version{
|
||||
VersionGA,
|
||||
VersionAlpha,
|
||||
VersionBeta,
|
||||
}
|
||||
|
||||
// AllServices are a list of all the services to generate code for. Keep
|
||||
// this list in lexiographical order by object type.
|
||||
var AllServices = []*ServiceInfo{
|
||||
{
|
||||
Object: "Address",
|
||||
Service: "Addresses",
|
||||
Resource: "addresses",
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&ga.AddressesService{}),
|
||||
},
|
||||
{
|
||||
Object: "Address",
|
||||
Service: "Addresses",
|
||||
Resource: "addresses",
|
||||
version: VersionAlpha,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&alpha.AddressesService{}),
|
||||
},
|
||||
{
|
||||
Object: "Address",
|
||||
Service: "Addresses",
|
||||
Resource: "addresses",
|
||||
version: VersionBeta,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&beta.AddressesService{}),
|
||||
},
|
||||
{
|
||||
Object: "Address",
|
||||
Service: "GlobalAddresses",
|
||||
Resource: "addresses",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.GlobalAddressesService{}),
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "BackendServices",
|
||||
Resource: "backendServices",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.BackendServicesService{}),
|
||||
additionalMethods: []string{
|
||||
"GetHealth",
|
||||
"Patch",
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "BackendServices",
|
||||
Resource: "backendServices",
|
||||
version: VersionBeta,
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&beta.BackendServicesService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
"SetSecurityPolicy",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "BackendServices",
|
||||
Resource: "backendServices",
|
||||
version: VersionAlpha,
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&alpha.BackendServicesService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
"SetSecurityPolicy",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "RegionBackendServices",
|
||||
Resource: "backendServices",
|
||||
version: VersionGA,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&ga.RegionBackendServicesService{}),
|
||||
additionalMethods: []string{
|
||||
"GetHealth",
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "BackendService",
|
||||
Service: "RegionBackendServices",
|
||||
Resource: "backendServices",
|
||||
version: VersionAlpha,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&alpha.RegionBackendServicesService{}),
|
||||
additionalMethods: []string{
|
||||
"GetHealth",
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Disk",
|
||||
Service: "Disks",
|
||||
Resource: "disks",
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&ga.DisksService{}),
|
||||
additionalMethods: []string{
|
||||
"Resize",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Disk",
|
||||
Service: "RegionDisks",
|
||||
Resource: "disks",
|
||||
version: VersionGA,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&ga.RegionDisksService{}),
|
||||
additionalMethods: []string{
|
||||
"Resize",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Firewall",
|
||||
Service: "Firewalls",
|
||||
Resource: "firewalls",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.FirewallsService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "ForwardingRule",
|
||||
Service: "ForwardingRules",
|
||||
Resource: "forwardingRules",
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&ga.ForwardingRulesService{}),
|
||||
},
|
||||
{
|
||||
Object: "ForwardingRule",
|
||||
Service: "ForwardingRules",
|
||||
Resource: "forwardingRules",
|
||||
version: VersionAlpha,
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&alpha.ForwardingRulesService{}),
|
||||
},
|
||||
{
|
||||
Object: "ForwardingRule",
|
||||
Service: "GlobalForwardingRules",
|
||||
Resource: "forwardingRules",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.GlobalForwardingRulesService{}),
|
||||
additionalMethods: []string{
|
||||
"SetTarget",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "HealthCheck",
|
||||
Service: "HealthChecks",
|
||||
Resource: "healthChecks",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.HealthChecksService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "HealthCheck",
|
||||
Service: "HealthChecks",
|
||||
Resource: "healthChecks",
|
||||
version: VersionAlpha,
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&alpha.HealthChecksService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "HealthCheck",
|
||||
Service: "HealthChecks",
|
||||
Resource: "healthChecks",
|
||||
version: VersionBeta,
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&beta.HealthChecksService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "HttpHealthCheck",
|
||||
Service: "HttpHealthChecks",
|
||||
Resource: "httpHealthChecks",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.HttpHealthChecksService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "HttpsHealthCheck",
|
||||
Service: "HttpsHealthChecks",
|
||||
Resource: "httpsHealthChecks",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.HttpsHealthChecksService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "InstanceGroup",
|
||||
Service: "InstanceGroups",
|
||||
Resource: "instanceGroups",
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&ga.InstanceGroupsService{}),
|
||||
additionalMethods: []string{
|
||||
"AddInstances",
|
||||
"ListInstances",
|
||||
"RemoveInstances",
|
||||
"SetNamedPorts",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Instance",
|
||||
Service: "Instances",
|
||||
Resource: "instances",
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&ga.InstancesService{}),
|
||||
additionalMethods: []string{
|
||||
"AttachDisk",
|
||||
"DetachDisk",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Instance",
|
||||
Service: "Instances",
|
||||
Resource: "instances",
|
||||
version: VersionBeta,
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&beta.InstancesService{}),
|
||||
additionalMethods: []string{
|
||||
"AttachDisk",
|
||||
"DetachDisk",
|
||||
"UpdateNetworkInterface",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Instance",
|
||||
Service: "Instances",
|
||||
Resource: "instances",
|
||||
version: VersionAlpha,
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&alpha.InstancesService{}),
|
||||
additionalMethods: []string{
|
||||
"AttachDisk",
|
||||
"DetachDisk",
|
||||
"UpdateNetworkInterface",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "NetworkEndpointGroup",
|
||||
Service: "NetworkEndpointGroups",
|
||||
Resource: "networkEndpointGroups",
|
||||
version: VersionAlpha,
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&alpha.NetworkEndpointGroupsService{}),
|
||||
additionalMethods: []string{
|
||||
"AttachNetworkEndpoints",
|
||||
"DetachNetworkEndpoints",
|
||||
"ListNetworkEndpoints",
|
||||
},
|
||||
options: AggregatedList,
|
||||
},
|
||||
{
|
||||
Object: "NetworkEndpointGroup",
|
||||
Service: "NetworkEndpointGroups",
|
||||
Resource: "networkEndpointGroups",
|
||||
version: VersionBeta,
|
||||
keyType: Zonal,
|
||||
serviceType: reflect.TypeOf(&beta.NetworkEndpointGroupsService{}),
|
||||
additionalMethods: []string{
|
||||
"AttachNetworkEndpoints",
|
||||
"DetachNetworkEndpoints",
|
||||
"ListNetworkEndpoints",
|
||||
},
|
||||
options: AggregatedList,
|
||||
},
|
||||
{
|
||||
Object: "Project",
|
||||
Service: "Projects",
|
||||
Resource: "projects",
|
||||
keyType: Global,
|
||||
// Generate only the stub with no methods.
|
||||
options: NoGet | NoList | NoInsert | NoDelete | CustomOps,
|
||||
serviceType: reflect.TypeOf(&ga.ProjectsService{}),
|
||||
},
|
||||
{
|
||||
Object: "Region",
|
||||
Service: "Regions",
|
||||
Resource: "regions",
|
||||
keyType: Global,
|
||||
options: ReadOnly,
|
||||
serviceType: reflect.TypeOf(&ga.RegionsService{}),
|
||||
},
|
||||
{
|
||||
Object: "Route",
|
||||
Service: "Routes",
|
||||
Resource: "routes",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.RoutesService{}),
|
||||
},
|
||||
{
|
||||
Object: "SecurityPolicy",
|
||||
Service: "SecurityPolicies",
|
||||
Resource: "securityPolicies",
|
||||
version: VersionBeta,
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&beta.SecurityPoliciesService{}),
|
||||
additionalMethods: []string{
|
||||
"AddRule",
|
||||
"GetRule",
|
||||
"Patch",
|
||||
"PatchRule",
|
||||
"RemoveRule",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "SslCertificate",
|
||||
Service: "SslCertificates",
|
||||
Resource: "sslCertificates",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.SslCertificatesService{}),
|
||||
},
|
||||
{
|
||||
Object: "TargetHttpProxy",
|
||||
Service: "TargetHttpProxies",
|
||||
Resource: "targetHttpProxies",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.TargetHttpProxiesService{}),
|
||||
additionalMethods: []string{
|
||||
"SetUrlMap",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "TargetHttpsProxy",
|
||||
Service: "TargetHttpsProxies",
|
||||
Resource: "targetHttpsProxies",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.TargetHttpsProxiesService{}),
|
||||
additionalMethods: []string{
|
||||
"SetSslCertificates",
|
||||
"SetUrlMap",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "TargetPool",
|
||||
Service: "TargetPools",
|
||||
Resource: "targetPools",
|
||||
keyType: Regional,
|
||||
serviceType: reflect.TypeOf(&ga.TargetPoolsService{}),
|
||||
additionalMethods: []string{
|
||||
"AddInstance",
|
||||
"RemoveInstance",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "UrlMap",
|
||||
Service: "UrlMaps",
|
||||
Resource: "urlMaps",
|
||||
keyType: Global,
|
||||
serviceType: reflect.TypeOf(&ga.UrlMapsService{}),
|
||||
additionalMethods: []string{
|
||||
"Update",
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: "Zone",
|
||||
Service: "Zones",
|
||||
Resource: "zones",
|
||||
keyType: Global,
|
||||
options: ReadOnly,
|
||||
serviceType: reflect.TypeOf(&ga.ZonesService{}),
|
||||
},
|
||||
}
|
337
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/method.go
generated
vendored
Normal file
337
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/method.go
generated
vendored
Normal file
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func newArg(t reflect.Type) *arg {
|
||||
ret := &arg{}
|
||||
|
||||
// Dereference the pointer types to get at the underlying concrete type.
|
||||
Loop:
|
||||
for {
|
||||
switch t.Kind() {
|
||||
case reflect.Ptr:
|
||||
ret.numPtr++
|
||||
t = t.Elem()
|
||||
default:
|
||||
ret.pkg = t.PkgPath()
|
||||
ret.typeName += t.Name()
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type arg struct {
|
||||
pkg, typeName string
|
||||
numPtr int
|
||||
}
|
||||
|
||||
func (a *arg) normalizedPkg() string {
|
||||
if a.pkg == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Strip the repo.../vendor/ prefix from the package path if present.
|
||||
parts := strings.Split(a.pkg, "/")
|
||||
// Remove vendor prefix.
|
||||
for i := 0; i < len(parts); i++ {
|
||||
if parts[i] == "vendor" {
|
||||
parts = parts[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
switch strings.Join(parts, "/") {
|
||||
case "google.golang.org/api/compute/v1":
|
||||
return "ga."
|
||||
case "google.golang.org/api/compute/v0.alpha":
|
||||
return "alpha."
|
||||
case "google.golang.org/api/compute/v0.beta":
|
||||
return "beta."
|
||||
default:
|
||||
panic(fmt.Errorf("unhandled package %q", a.pkg))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *arg) String() string {
|
||||
var ret string
|
||||
for i := 0; i < a.numPtr; i++ {
|
||||
ret += "*"
|
||||
}
|
||||
ret += a.normalizedPkg()
|
||||
ret += a.typeName
|
||||
return ret
|
||||
}
|
||||
|
||||
// newMethod returns a newly initialized method.
|
||||
func newMethod(s *ServiceInfo, m reflect.Method) *Method {
|
||||
ret := &Method{
|
||||
ServiceInfo: s,
|
||||
m: m,
|
||||
kind: MethodOperation,
|
||||
ReturnType: "",
|
||||
}
|
||||
ret.init()
|
||||
return ret
|
||||
}
|
||||
|
||||
// MethodKind is the type of method that we are generated code for.
|
||||
type MethodKind int
|
||||
|
||||
const (
|
||||
// MethodOperation is a long running method that returns an operation.
|
||||
MethodOperation MethodKind = iota
|
||||
// MethodGet is a method that immediately returns some data.
|
||||
MethodGet MethodKind = iota
|
||||
// MethodPaged is a method that returns a paged set of data.
|
||||
MethodPaged MethodKind = iota
|
||||
)
|
||||
|
||||
// Method is used to generate the calling code for non-standard methods.
|
||||
type Method struct {
|
||||
*ServiceInfo
|
||||
m reflect.Method
|
||||
|
||||
kind MethodKind
|
||||
// ReturnType is the return type for the method.
|
||||
ReturnType string
|
||||
// ItemType is the type of the individual elements returns from a
|
||||
// Pages() call. This is only applicable for MethodPaged kind.
|
||||
ItemType string
|
||||
}
|
||||
|
||||
// IsOperation is true if the method is an Operation.
|
||||
func (m *Method) IsOperation() bool {
|
||||
return m.kind == MethodOperation
|
||||
}
|
||||
|
||||
// IsPaged is true if the method paged.
|
||||
func (m *Method) IsPaged() bool {
|
||||
return m.kind == MethodPaged
|
||||
}
|
||||
|
||||
// IsGet is true if the method simple get.
|
||||
func (m *Method) IsGet() bool {
|
||||
return m.kind == MethodGet
|
||||
}
|
||||
|
||||
// argsSkip is the number of arguments to skip when generating the
|
||||
// synthesized method.
|
||||
func (m *Method) argsSkip() int {
|
||||
switch m.keyType {
|
||||
case Zonal:
|
||||
return 4
|
||||
case Regional:
|
||||
return 4
|
||||
case Global:
|
||||
return 3
|
||||
}
|
||||
panic(fmt.Errorf("invalid KeyType %v", m.keyType))
|
||||
}
|
||||
|
||||
// args return a list of arguments to the method, skipping the first skip
|
||||
// elements. If nameArgs is true, then the arguments will include a generated
|
||||
// parameter name (arg<N>). prefix will be added to the parameters.
|
||||
func (m *Method) args(skip int, nameArgs bool, prefix []string) []string {
|
||||
var args []*arg
|
||||
fType := m.m.Func.Type()
|
||||
for i := 0; i < fType.NumIn(); i++ {
|
||||
t := fType.In(i)
|
||||
args = append(args, newArg(t))
|
||||
}
|
||||
|
||||
var a []string
|
||||
for i := skip; i < fType.NumIn(); i++ {
|
||||
if nameArgs {
|
||||
a = append(a, fmt.Sprintf("arg%d %s", i-skip, args[i]))
|
||||
} else {
|
||||
a = append(a, args[i].String())
|
||||
}
|
||||
}
|
||||
return append(prefix, a...)
|
||||
}
|
||||
|
||||
// init the method. This performs some rudimentary static checking as well as
|
||||
// determines the kind of method by looking at the shape (method signature) of
|
||||
// the object.
|
||||
func (m *Method) init() {
|
||||
fType := m.m.Func.Type()
|
||||
if fType.NumIn() < m.argsSkip() {
|
||||
err := fmt.Errorf("method %q.%q, arity = %d which is less than required (< %d)",
|
||||
m.Service, m.Name(), fType.NumIn(), m.argsSkip())
|
||||
panic(err)
|
||||
}
|
||||
// Skipped args should all be string (they will be projectID, zone, region etc).
|
||||
for i := 1; i < m.argsSkip(); i++ {
|
||||
if fType.In(i).Kind() != reflect.String {
|
||||
panic(fmt.Errorf("method %q.%q: skipped args can only be strings", m.Service, m.Name()))
|
||||
}
|
||||
}
|
||||
// Return of the method must return a single value of type *xxxCall.
|
||||
if fType.NumOut() != 1 || fType.Out(0).Kind() != reflect.Ptr || !strings.HasSuffix(fType.Out(0).Elem().Name(), "Call") {
|
||||
panic(fmt.Errorf("method %q.%q: generator only supports methods returning an *xxxCall object",
|
||||
m.Service, m.Name()))
|
||||
}
|
||||
returnType := fType.Out(0)
|
||||
returnTypeName := fType.Out(0).Elem().Name()
|
||||
// xxxCall must have a Do() method.
|
||||
doMethod, ok := returnType.MethodByName("Do")
|
||||
if !ok {
|
||||
panic(fmt.Errorf("method %q.%q: return type %q does not have a Do() method",
|
||||
m.Service, m.Name(), returnTypeName))
|
||||
}
|
||||
_, hasPages := returnType.MethodByName("Pages")
|
||||
// Do() method must return (*T, error).
|
||||
switch doMethod.Func.Type().NumOut() {
|
||||
case 2:
|
||||
out0 := doMethod.Func.Type().Out(0)
|
||||
if out0.Kind() != reflect.Ptr {
|
||||
panic(fmt.Errorf("method %q.%q: return type %q of Do() = S, _; S must be pointer type (%v)",
|
||||
m.Service, m.Name(), returnTypeName, out0))
|
||||
}
|
||||
m.ReturnType = out0.Elem().Name()
|
||||
switch {
|
||||
case out0.Elem().Name() == "Operation":
|
||||
m.kind = MethodOperation
|
||||
case hasPages:
|
||||
m.kind = MethodPaged
|
||||
// Pages() returns a xxxList that has the actual list
|
||||
// of objects in the xxxList.Items field.
|
||||
listType := out0.Elem()
|
||||
itemsField, ok := listType.FieldByName("Items")
|
||||
if !ok {
|
||||
panic(fmt.Errorf("method %q.%q: paged return type %q does not have a .Items field", m.Service, m.Name(), listType.Name()))
|
||||
}
|
||||
// itemsField will be a []*ItemType. Dereference to
|
||||
// extract the ItemType.
|
||||
itemsType := itemsField.Type
|
||||
if itemsType.Kind() != reflect.Slice && itemsType.Elem().Kind() != reflect.Ptr {
|
||||
panic(fmt.Errorf("method %q.%q: paged return type %q.Items is not an array of pointers", m.Service, m.Name(), listType.Name()))
|
||||
}
|
||||
m.ItemType = itemsType.Elem().Elem().Name()
|
||||
default:
|
||||
m.kind = MethodGet
|
||||
}
|
||||
// Second argument must be "error".
|
||||
if doMethod.Func.Type().Out(1).Name() != "error" {
|
||||
panic(fmt.Errorf("method %q.%q: return type %q of Do() = S, T; T must be 'error'",
|
||||
m.Service, m.Name(), returnTypeName))
|
||||
}
|
||||
break
|
||||
default:
|
||||
panic(fmt.Errorf("method %q.%q: %q Do() return type is not handled by the generator",
|
||||
m.Service, m.Name(), returnTypeName))
|
||||
}
|
||||
}
|
||||
|
||||
// Name is the name of the method.
|
||||
func (m *Method) Name() string {
|
||||
return m.m.Name
|
||||
}
|
||||
|
||||
// CallArgs is a list of comma separated "argN" used for calling the method.
|
||||
// For example, if the method has two additional arguments, this will return
|
||||
// "arg0, arg1".
|
||||
func (m *Method) CallArgs() string {
|
||||
var args []string
|
||||
for i := m.argsSkip(); i < m.m.Func.Type().NumIn(); i++ {
|
||||
args = append(args, fmt.Sprintf("arg%d", i-m.argsSkip()))
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf(", %s", strings.Join(args, ", "))
|
||||
}
|
||||
|
||||
// MockHookName is the name of the hook function in the mock.
|
||||
func (m *Method) MockHookName() string {
|
||||
return m.m.Name + "Hook"
|
||||
}
|
||||
|
||||
// MockHook is the definition of the hook function.
|
||||
func (m *Method) MockHook() string {
|
||||
args := m.args(m.argsSkip(), false, []string{
|
||||
"context.Context",
|
||||
"*meta.Key",
|
||||
})
|
||||
if m.kind == MethodPaged {
|
||||
args = append(args, "*filter.F")
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("*%s", m.MockWrapType()))
|
||||
|
||||
switch m.kind {
|
||||
case MethodOperation:
|
||||
return fmt.Sprintf("%v func(%v) error", m.MockHookName(), strings.Join(args, ", "))
|
||||
case MethodGet:
|
||||
return fmt.Sprintf("%v func(%v) (*%v.%v, error)", m.MockHookName(), strings.Join(args, ", "), m.Version(), m.ReturnType)
|
||||
case MethodPaged:
|
||||
return fmt.Sprintf("%v func(%v) ([]*%v.%v, error)", m.MockHookName(), strings.Join(args, ", "), m.Version(), m.ItemType)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid method kind: %v", m.kind))
|
||||
}
|
||||
}
|
||||
|
||||
// FcnArgs is the function signature for the definition of the method.
|
||||
func (m *Method) FcnArgs() string {
|
||||
args := m.args(m.argsSkip(), true, []string{
|
||||
"ctx context.Context",
|
||||
"key *meta.Key",
|
||||
})
|
||||
if m.kind == MethodPaged {
|
||||
args = append(args, "fl *filter.F")
|
||||
}
|
||||
|
||||
switch m.kind {
|
||||
case MethodOperation:
|
||||
return fmt.Sprintf("%v(%v) error", m.m.Name, strings.Join(args, ", "))
|
||||
case MethodGet:
|
||||
return fmt.Sprintf("%v(%v) (*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ReturnType)
|
||||
case MethodPaged:
|
||||
return fmt.Sprintf("%v(%v) ([]*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ItemType)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid method kind: %v", m.kind))
|
||||
}
|
||||
}
|
||||
|
||||
// InterfaceFunc is the function declaration of the method in the interface.
|
||||
func (m *Method) InterfaceFunc() string {
|
||||
args := []string{
|
||||
"context.Context",
|
||||
"*meta.Key",
|
||||
}
|
||||
args = m.args(m.argsSkip(), false, args)
|
||||
if m.kind == MethodPaged {
|
||||
args = append(args, "*filter.F")
|
||||
}
|
||||
|
||||
switch m.kind {
|
||||
case MethodOperation:
|
||||
return fmt.Sprintf("%v(%v) error", m.m.Name, strings.Join(args, ", "))
|
||||
case MethodGet:
|
||||
return fmt.Sprintf("%v(%v) (*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ReturnType)
|
||||
case MethodPaged:
|
||||
return fmt.Sprintf("%v(%v) ([]*%v.%v, error)", m.m.Name, strings.Join(args, ", "), m.Version(), m.ItemType)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid method kind: %v", m.kind))
|
||||
}
|
||||
}
|
300
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/service.go
generated
vendored
Normal file
300
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta/service.go
generated
vendored
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 meta
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// ServiceInfo defines the entry for a Service that code will be generated for.
|
||||
type ServiceInfo struct {
|
||||
// Object is the Go name of the object type that the service deals
|
||||
// with. Example: "ForwardingRule".
|
||||
Object string
|
||||
// Service is the Go name of the service struct i.e. where the methods
|
||||
// are defined. Examples: "GlobalForwardingRules".
|
||||
Service string
|
||||
// Resource is the plural noun of the resource in the compute API URL (e.g.
|
||||
// "forwardingRules").
|
||||
Resource string
|
||||
// version if unspecified will be assumed to be VersionGA.
|
||||
version Version
|
||||
keyType KeyType
|
||||
serviceType reflect.Type
|
||||
|
||||
additionalMethods []string
|
||||
options int
|
||||
aggregatedListField string
|
||||
}
|
||||
|
||||
// Version returns the version of the Service, defaulting to GA if APIVersion
|
||||
// is empty.
|
||||
func (i *ServiceInfo) Version() Version {
|
||||
if i.version == "" {
|
||||
return VersionGA
|
||||
}
|
||||
return i.version
|
||||
}
|
||||
|
||||
// VersionTitle returns the capitalized golang CamelCase name for the version.
|
||||
func (i *ServiceInfo) VersionTitle() string {
|
||||
switch i.Version() {
|
||||
case VersionGA:
|
||||
return "GA"
|
||||
case VersionAlpha:
|
||||
return "Alpha"
|
||||
case VersionBeta:
|
||||
return "Beta"
|
||||
}
|
||||
panic(fmt.Errorf("invalid version %q", i.Version()))
|
||||
}
|
||||
|
||||
// WrapType is the name of the wrapper service type.
|
||||
func (i *ServiceInfo) WrapType() string {
|
||||
switch i.Version() {
|
||||
case VersionGA:
|
||||
return i.Service
|
||||
case VersionAlpha:
|
||||
return "Alpha" + i.Service
|
||||
case VersionBeta:
|
||||
return "Beta" + i.Service
|
||||
}
|
||||
return "Invalid"
|
||||
}
|
||||
|
||||
// WrapTypeOps is the name of the additional operations type.
|
||||
func (i *ServiceInfo) WrapTypeOps() string {
|
||||
return i.WrapType() + "Ops"
|
||||
}
|
||||
|
||||
// FQObjectType is fully qualified name of the object (e.g. compute.Instance).
|
||||
func (i *ServiceInfo) FQObjectType() string {
|
||||
return fmt.Sprintf("%v.%v", i.Version(), i.Object)
|
||||
}
|
||||
|
||||
// ObjectListType is the compute List type for the object (contains Items field).
|
||||
func (i *ServiceInfo) ObjectListType() string {
|
||||
return fmt.Sprintf("%v.%vList", i.Version(), i.Object)
|
||||
}
|
||||
|
||||
// ObjectAggregatedListType is the compute List type for the object (contains Items field).
|
||||
func (i *ServiceInfo) ObjectAggregatedListType() string {
|
||||
return fmt.Sprintf("%v.%vAggregatedList", i.Version(), i.Object)
|
||||
}
|
||||
|
||||
// MockWrapType is the name of the concrete mock for this type.
|
||||
func (i *ServiceInfo) MockWrapType() string {
|
||||
return "Mock" + i.WrapType()
|
||||
}
|
||||
|
||||
// MockField is the name of the field in the mock struct.
|
||||
func (i *ServiceInfo) MockField() string {
|
||||
return "Mock" + i.WrapType()
|
||||
}
|
||||
|
||||
// GCEWrapType is the name of the GCE wrapper type.
|
||||
func (i *ServiceInfo) GCEWrapType() string {
|
||||
return "GCE" + i.WrapType()
|
||||
}
|
||||
|
||||
// Field is the name of the GCE struct.
|
||||
func (i *ServiceInfo) Field() string {
|
||||
return "gce" + i.WrapType()
|
||||
}
|
||||
|
||||
// Methods returns a list of additional methods to generate code for.
|
||||
func (i *ServiceInfo) Methods() []*Method {
|
||||
methods := map[string]bool{}
|
||||
for _, m := range i.additionalMethods {
|
||||
methods[m] = true
|
||||
}
|
||||
|
||||
var ret []*Method
|
||||
for j := 0; j < i.serviceType.NumMethod(); j++ {
|
||||
m := i.serviceType.Method(j)
|
||||
if _, ok := methods[m.Name]; !ok {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, newMethod(i, m))
|
||||
methods[m.Name] = false
|
||||
}
|
||||
|
||||
for k, b := range methods {
|
||||
if b {
|
||||
panic(fmt.Errorf("method %q was not found in service %q", k, i.Service))
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// KeyIsGlobal is true if the key is global.
|
||||
func (i *ServiceInfo) KeyIsGlobal() bool {
|
||||
return i.keyType == Global
|
||||
}
|
||||
|
||||
// KeyIsRegional is true if the key is regional.
|
||||
func (i *ServiceInfo) KeyIsRegional() bool {
|
||||
return i.keyType == Regional
|
||||
}
|
||||
|
||||
// KeyIsZonal is true if the key is zonal.
|
||||
func (i *ServiceInfo) KeyIsZonal() bool {
|
||||
return i.keyType == Zonal
|
||||
}
|
||||
|
||||
// KeyIsProject is true if the key represents the project resource.
|
||||
func (i *ServiceInfo) KeyIsProject() bool {
|
||||
// Projects are a special resource for ResourceId because there is no 'key' value. This func
|
||||
// is used by the generator to not accept a key parameter.
|
||||
return i.Service == "Projects"
|
||||
}
|
||||
|
||||
// MakeKey returns the call used to create the appropriate key type.
|
||||
func (i *ServiceInfo) MakeKey(name, location string) string {
|
||||
switch i.keyType {
|
||||
case Global:
|
||||
return fmt.Sprintf("GlobalKey(%q)", name)
|
||||
case Regional:
|
||||
return fmt.Sprintf("RegionalKey(%q, %q)", name, location)
|
||||
case Zonal:
|
||||
return fmt.Sprintf("ZonalKey(%q, %q)", name, location)
|
||||
}
|
||||
return "Invalid"
|
||||
}
|
||||
|
||||
// GenerateGet is true if the method is to be generated.
|
||||
func (i *ServiceInfo) GenerateGet() bool {
|
||||
return i.options&NoGet == 0
|
||||
}
|
||||
|
||||
// GenerateList is true if the method is to be generated.
|
||||
func (i *ServiceInfo) GenerateList() bool {
|
||||
return i.options&NoList == 0
|
||||
}
|
||||
|
||||
// GenerateDelete is true if the method is to be generated.
|
||||
func (i *ServiceInfo) GenerateDelete() bool {
|
||||
return i.options&NoDelete == 0
|
||||
}
|
||||
|
||||
// GenerateInsert is true if the method is to be generated.
|
||||
func (i *ServiceInfo) GenerateInsert() bool {
|
||||
return i.options&NoInsert == 0
|
||||
}
|
||||
|
||||
// GenerateCustomOps is true if we should generated a xxxOps interface for
|
||||
// adding additional methods to the generated interface.
|
||||
func (i *ServiceInfo) GenerateCustomOps() bool {
|
||||
return i.options&CustomOps != 0
|
||||
}
|
||||
|
||||
// AggregatedList is true if the method is to be generated.
|
||||
func (i *ServiceInfo) AggregatedList() bool {
|
||||
return i.options&AggregatedList != 0
|
||||
}
|
||||
|
||||
// AggregatedListField is the name of the field used for the aggregated list
|
||||
// call. This is typically the same as the name of the service, but can be
|
||||
// customized by setting the aggregatedListField field.
|
||||
func (i *ServiceInfo) AggregatedListField() string {
|
||||
if i.aggregatedListField == "" {
|
||||
return i.Service
|
||||
}
|
||||
return i.aggregatedListField
|
||||
}
|
||||
|
||||
// ServiceGroup is a grouping of the same service but at different API versions.
|
||||
type ServiceGroup struct {
|
||||
Alpha *ServiceInfo
|
||||
Beta *ServiceInfo
|
||||
GA *ServiceInfo
|
||||
}
|
||||
|
||||
// Service returns any ServiceInfo string belonging to the ServiceGroup.
|
||||
func (sg *ServiceGroup) Service() string {
|
||||
return sg.ServiceInfo().Service
|
||||
}
|
||||
|
||||
// ServiceInfo returns any ServiceInfo object belonging to the ServiceGroup.
|
||||
func (sg *ServiceGroup) ServiceInfo() *ServiceInfo {
|
||||
switch {
|
||||
case sg.GA != nil:
|
||||
return sg.GA
|
||||
case sg.Alpha != nil:
|
||||
return sg.Alpha
|
||||
case sg.Beta != nil:
|
||||
return sg.Beta
|
||||
default:
|
||||
panic(errors.New("service group is empty"))
|
||||
}
|
||||
}
|
||||
|
||||
// HasGA returns true if this object has a GA representation.
|
||||
func (sg *ServiceGroup) HasGA() bool {
|
||||
return sg.GA != nil
|
||||
}
|
||||
|
||||
// HasAlpha returns true if this object has a Alpha representation.
|
||||
func (sg *ServiceGroup) HasAlpha() bool {
|
||||
return sg.Alpha != nil
|
||||
}
|
||||
|
||||
// HasBeta returns true if this object has a Beta representation.
|
||||
func (sg *ServiceGroup) HasBeta() bool {
|
||||
return sg.Beta != nil
|
||||
}
|
||||
|
||||
// groupServices together by version.
|
||||
func groupServices(services []*ServiceInfo) map[string]*ServiceGroup {
|
||||
ret := map[string]*ServiceGroup{}
|
||||
for _, si := range services {
|
||||
if _, ok := ret[si.Service]; !ok {
|
||||
ret[si.Service] = &ServiceGroup{}
|
||||
}
|
||||
group := ret[si.Service]
|
||||
switch si.Version() {
|
||||
case VersionAlpha:
|
||||
group.Alpha = si
|
||||
case VersionBeta:
|
||||
group.Beta = si
|
||||
case VersionGA:
|
||||
group.GA = si
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// AllServicesByGroup is a map of service name to ServicesGroup.
|
||||
var AllServicesByGroup map[string]*ServiceGroup
|
||||
|
||||
// SortedServicesGroups is a slice of Servicegroup sorted by Service name.
|
||||
var SortedServicesGroups []*ServiceGroup
|
||||
|
||||
func init() {
|
||||
AllServicesByGroup = groupServices(AllServices)
|
||||
|
||||
for _, sg := range AllServicesByGroup {
|
||||
SortedServicesGroups = append(SortedServicesGroups, sg)
|
||||
}
|
||||
sort.Slice(SortedServicesGroups, func(i, j int) bool {
|
||||
return SortedServicesGroups[i].Service() < SortedServicesGroups[j].Service()
|
||||
})
|
||||
}
|
640
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock/mock.go
generated
vendored
Normal file
640
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock/mock.go
generated
vendored
Normal file
|
@ -0,0 +1,640 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 mock encapsulates mocks for testing GCE provider functionality.
|
||||
// These methods are used to override the mock objects' methods in order to
|
||||
// intercept the standard processing and to add custom logic for test purposes.
|
||||
//
|
||||
// // Example usage:
|
||||
// cloud := cloud.NewMockGCE()
|
||||
// cloud.MockTargetPools.AddInstanceHook = mock.AddInstanceHook
|
||||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
cloud "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud"
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter"
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
|
||||
alpha "google.golang.org/api/compute/v0.alpha"
|
||||
beta "google.golang.org/api/compute/v0.beta"
|
||||
ga "google.golang.org/api/compute/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
var (
|
||||
// InUseError is a shared variable with error code StatusBadRequest for error verification.
|
||||
InUseError = &googleapi.Error{Code: http.StatusBadRequest, Message: "It's being used by god."}
|
||||
// InternalServerError is shared variable with error code StatusInternalServerError for error verification.
|
||||
InternalServerError = &googleapi.Error{Code: http.StatusInternalServerError}
|
||||
// UnauthorizedErr wraps a Google API error with code StatusForbidden.
|
||||
UnauthorizedErr = &googleapi.Error{Code: http.StatusForbidden}
|
||||
)
|
||||
|
||||
// gceObject is an abstraction of all GCE API object in go client
|
||||
type gceObject interface {
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
// AddInstanceHook mocks adding a Instance to MockTargetPools
|
||||
func AddInstanceHook(ctx context.Context, key *meta.Key, req *ga.TargetPoolsAddInstanceRequest, m *cloud.MockTargetPools) error {
|
||||
pool, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in TargetPools", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
for _, instance := range req.Instances {
|
||||
pool.Instances = append(pool.Instances, instance.Instance)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveInstanceHook mocks removing a Instance from MockTargetPools
|
||||
func RemoveInstanceHook(ctx context.Context, key *meta.Key, req *ga.TargetPoolsRemoveInstanceRequest, m *cloud.MockTargetPools) error {
|
||||
pool, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in TargetPools", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
for _, instanceToRemove := range req.Instances {
|
||||
for i, instance := range pool.Instances {
|
||||
if instanceToRemove.Instance == instance {
|
||||
// Delete instance from pool.Instances without preserving order
|
||||
pool.Instances[i] = pool.Instances[len(pool.Instances)-1]
|
||||
pool.Instances = pool.Instances[:len(pool.Instances)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertAndInsertAlphaForwardingRule(key *meta.Key, obj gceObject, mRules map[meta.Key]*cloud.MockForwardingRulesObj, version meta.Version, projectID string) (bool, error) {
|
||||
if !key.Valid() {
|
||||
return true, fmt.Errorf("invalid GCE key (%+v)", key)
|
||||
}
|
||||
|
||||
if _, ok := mRules[*key]; ok {
|
||||
err := &googleapi.Error{
|
||||
Code: http.StatusConflict,
|
||||
Message: fmt.Sprintf("MockForwardingRule %v exists", key),
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
|
||||
enc, err := obj.MarshalJSON()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
var fwdRule alpha.ForwardingRule
|
||||
if err := json.Unmarshal(enc, &fwdRule); err != nil {
|
||||
return true, err
|
||||
}
|
||||
// Set the default values for the Alpha fields.
|
||||
if fwdRule.NetworkTier == "" {
|
||||
fwdRule.NetworkTier = cloud.NetworkTierDefault.ToGCEValue()
|
||||
}
|
||||
|
||||
fwdRule.Name = key.Name
|
||||
if fwdRule.SelfLink == "" {
|
||||
fwdRule.SelfLink = cloud.SelfLink(version, projectID, "forwardingRules", key)
|
||||
}
|
||||
|
||||
mRules[*key] = &cloud.MockForwardingRulesObj{Obj: fwdRule}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// InsertFwdRuleHook mocks inserting a ForwardingRule. ForwardingRules are
|
||||
// expected to default to Premium tier if no NetworkTier is specified.
|
||||
func InsertFwdRuleHook(ctx context.Context, key *meta.Key, obj *ga.ForwardingRule, m *cloud.MockForwardingRules) (bool, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, meta.VersionGA, "forwardingRules")
|
||||
return convertAndInsertAlphaForwardingRule(key, obj, m.Objects, meta.VersionGA, projectID)
|
||||
}
|
||||
|
||||
// InsertBetaFwdRuleHook mocks inserting a BetaForwardingRule.
|
||||
func InsertBetaFwdRuleHook(ctx context.Context, key *meta.Key, obj *beta.ForwardingRule, m *cloud.MockForwardingRules) (bool, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, meta.VersionBeta, "forwardingRules")
|
||||
return convertAndInsertAlphaForwardingRule(key, obj, m.Objects, meta.VersionBeta, projectID)
|
||||
}
|
||||
|
||||
// InsertAlphaFwdRuleHook mocks inserting an AlphaForwardingRule.
|
||||
func InsertAlphaFwdRuleHook(ctx context.Context, key *meta.Key, obj *alpha.ForwardingRule, m *cloud.MockForwardingRules) (bool, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, meta.VersionAlpha, "forwardingRules")
|
||||
return convertAndInsertAlphaForwardingRule(key, obj, m.Objects, meta.VersionAlpha, projectID)
|
||||
}
|
||||
|
||||
// AddressAttributes maps from Address key to a map of Instances
|
||||
type AddressAttributes struct {
|
||||
IPCounter int // Used to assign Addresses with no IP a unique IP address
|
||||
}
|
||||
|
||||
func convertAndInsertAlphaAddress(key *meta.Key, obj gceObject, mAddrs map[meta.Key]*cloud.MockAddressesObj, version meta.Version, projectID string, addressAttrs AddressAttributes) (bool, error) {
|
||||
if !key.Valid() {
|
||||
return true, fmt.Errorf("invalid GCE key (%+v)", key)
|
||||
}
|
||||
|
||||
if _, ok := mAddrs[*key]; ok {
|
||||
err := &googleapi.Error{
|
||||
Code: http.StatusConflict,
|
||||
Message: fmt.Sprintf("MockAddresses %v exists", key),
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
|
||||
enc, err := obj.MarshalJSON()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
var addr alpha.Address
|
||||
if err := json.Unmarshal(enc, &addr); err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
// Set default address type if not present.
|
||||
if addr.AddressType == "" {
|
||||
addr.AddressType = string(cloud.SchemeExternal)
|
||||
}
|
||||
|
||||
var existingAddresses []*ga.Address
|
||||
for _, obj := range mAddrs {
|
||||
existingAddresses = append(existingAddresses, obj.ToGA())
|
||||
}
|
||||
|
||||
for _, existingAddr := range existingAddresses {
|
||||
if addr.Address == existingAddr.Address {
|
||||
msg := fmt.Sprintf("MockAddresses IP %v in use", addr.Address)
|
||||
|
||||
// When the IP is already in use, this call returns a StatusBadRequest
|
||||
// if the address is an external address, and StatusConflict if an
|
||||
// internal address. This is to be consistent with actual GCE API.
|
||||
errorCode := http.StatusConflict
|
||||
if addr.AddressType == string(cloud.SchemeExternal) {
|
||||
errorCode = http.StatusBadRequest
|
||||
}
|
||||
|
||||
return true, &googleapi.Error{Code: errorCode, Message: msg}
|
||||
}
|
||||
}
|
||||
|
||||
// Set default values used in tests
|
||||
addr.Name = key.Name
|
||||
if addr.SelfLink == "" {
|
||||
addr.SelfLink = cloud.SelfLink(version, projectID, "addresses", key)
|
||||
}
|
||||
|
||||
if addr.Address == "" {
|
||||
addr.Address = fmt.Sprintf("1.2.3.%d", addressAttrs.IPCounter)
|
||||
addressAttrs.IPCounter++
|
||||
}
|
||||
|
||||
// Set the default values for the Alpha fields.
|
||||
if addr.NetworkTier == "" {
|
||||
addr.NetworkTier = cloud.NetworkTierDefault.ToGCEValue()
|
||||
}
|
||||
|
||||
mAddrs[*key] = &cloud.MockAddressesObj{Obj: addr}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// InsertAddressHook mocks inserting an Address.
|
||||
func InsertAddressHook(ctx context.Context, key *meta.Key, obj *ga.Address, m *cloud.MockAddresses) (bool, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, meta.VersionGA, "addresses")
|
||||
return convertAndInsertAlphaAddress(key, obj, m.Objects, meta.VersionGA, projectID, m.X.(AddressAttributes))
|
||||
}
|
||||
|
||||
// InsertBetaAddressHook mocks inserting a BetaAddress.
|
||||
func InsertBetaAddressHook(ctx context.Context, key *meta.Key, obj *beta.Address, m *cloud.MockAddresses) (bool, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, meta.VersionBeta, "addresses")
|
||||
return convertAndInsertAlphaAddress(key, obj, m.Objects, meta.VersionBeta, projectID, m.X.(AddressAttributes))
|
||||
}
|
||||
|
||||
// InsertAlphaAddressHook mocks inserting an Address. Addresses are expected to
|
||||
// default to Premium tier if no NetworkTier is specified.
|
||||
func InsertAlphaAddressHook(ctx context.Context, key *meta.Key, obj *alpha.Address, m *cloud.MockAlphaAddresses) (bool, error) {
|
||||
m.Lock.Lock()
|
||||
defer m.Lock.Unlock()
|
||||
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, meta.VersionBeta, "addresses")
|
||||
return convertAndInsertAlphaAddress(key, obj, m.Objects, meta.VersionAlpha, projectID, m.X.(AddressAttributes))
|
||||
}
|
||||
|
||||
// InstanceGroupAttributes maps from InstanceGroup key to a map of Instances
|
||||
type InstanceGroupAttributes struct {
|
||||
InstanceMap map[meta.Key]map[string]*ga.InstanceWithNamedPorts
|
||||
Lock *sync.Mutex
|
||||
}
|
||||
|
||||
// AddInstances adds a list of Instances passed by InstanceReference
|
||||
func (igAttrs *InstanceGroupAttributes) AddInstances(key *meta.Key, instanceRefs []*ga.InstanceReference) error {
|
||||
igAttrs.Lock.Lock()
|
||||
defer igAttrs.Lock.Unlock()
|
||||
|
||||
instancesWithNamedPorts, ok := igAttrs.InstanceMap[*key]
|
||||
if !ok {
|
||||
instancesWithNamedPorts = make(map[string]*ga.InstanceWithNamedPorts)
|
||||
}
|
||||
|
||||
for _, instance := range instanceRefs {
|
||||
iWithPort := &ga.InstanceWithNamedPorts{
|
||||
Instance: instance.Instance,
|
||||
}
|
||||
|
||||
instancesWithNamedPorts[instance.Instance] = iWithPort
|
||||
}
|
||||
|
||||
igAttrs.InstanceMap[*key] = instancesWithNamedPorts
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveInstances removes a list of Instances passed by InstanceReference
|
||||
func (igAttrs *InstanceGroupAttributes) RemoveInstances(key *meta.Key, instanceRefs []*ga.InstanceReference) error {
|
||||
igAttrs.Lock.Lock()
|
||||
defer igAttrs.Lock.Unlock()
|
||||
|
||||
instancesWithNamedPorts, ok := igAttrs.InstanceMap[*key]
|
||||
if !ok {
|
||||
instancesWithNamedPorts = make(map[string]*ga.InstanceWithNamedPorts)
|
||||
}
|
||||
|
||||
for _, instanceToRemove := range instanceRefs {
|
||||
if _, ok := instancesWithNamedPorts[instanceToRemove.Instance]; ok {
|
||||
delete(instancesWithNamedPorts, instanceToRemove.Instance)
|
||||
} else {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusBadRequest,
|
||||
Message: fmt.Sprintf("%s is not a member of %s", instanceToRemove.Instance, key.String()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
igAttrs.InstanceMap[*key] = instancesWithNamedPorts
|
||||
return nil
|
||||
}
|
||||
|
||||
// List gets a list of InstanceWithNamedPorts
|
||||
func (igAttrs *InstanceGroupAttributes) List(key *meta.Key) []*ga.InstanceWithNamedPorts {
|
||||
igAttrs.Lock.Lock()
|
||||
defer igAttrs.Lock.Unlock()
|
||||
|
||||
instancesWithNamedPorts, ok := igAttrs.InstanceMap[*key]
|
||||
if !ok {
|
||||
instancesWithNamedPorts = make(map[string]*ga.InstanceWithNamedPorts)
|
||||
}
|
||||
|
||||
var instanceList []*ga.InstanceWithNamedPorts
|
||||
for _, val := range instancesWithNamedPorts {
|
||||
instanceList = append(instanceList, val)
|
||||
}
|
||||
|
||||
return instanceList
|
||||
}
|
||||
|
||||
// AddInstancesHook mocks adding instances from an InstanceGroup
|
||||
func AddInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsAddInstancesRequest, m *cloud.MockInstanceGroups) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
var attrs InstanceGroupAttributes
|
||||
attrs = m.X.(InstanceGroupAttributes)
|
||||
attrs.AddInstances(key, req.Instances)
|
||||
m.X = attrs
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListInstancesHook mocks listing instances from an InstanceGroup
|
||||
func ListInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsListInstancesRequest, filter *filter.F, m *cloud.MockInstanceGroups) ([]*ga.InstanceWithNamedPorts, error) {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return nil, &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
var attrs InstanceGroupAttributes
|
||||
attrs = m.X.(InstanceGroupAttributes)
|
||||
instances := attrs.List(key)
|
||||
|
||||
return instances, nil
|
||||
}
|
||||
|
||||
// RemoveInstancesHook mocks removing instances from an InstanceGroup
|
||||
func RemoveInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsRemoveInstancesRequest, m *cloud.MockInstanceGroups) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
var attrs InstanceGroupAttributes
|
||||
attrs = m.X.(InstanceGroupAttributes)
|
||||
attrs.RemoveInstances(key, req.Instances)
|
||||
m.X = attrs
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateFirewallHook defines the hook for updating a Firewall. It replaces the
|
||||
// object with the same key in the mock with the updated object.
|
||||
func UpdateFirewallHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m *cloud.MockFirewalls) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in Firewalls", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "firewalls")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "firewalls", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockFirewallsObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateHealthCheckHook defines the hook for updating a HealthCheck. It
|
||||
// replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateHealthCheckHook(ctx context.Context, key *meta.Key, obj *ga.HealthCheck, m *cloud.MockHealthChecks) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in HealthChecks", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "healthChecks")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "healthChecks", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockHealthChecksObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateRegionBackendServiceHook defines the hook for updating a Region
|
||||
// BackendsService. It replaces the object with the same key in the mock with
|
||||
// the updated object.
|
||||
func UpdateRegionBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.BackendService, m *cloud.MockRegionBackendServices) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in RegionBackendServices", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "backendServices")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "backendServices", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockRegionBackendServicesObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateBackendServiceHook defines the hook for updating a BackendService.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.BackendService, m *cloud.MockBackendServices) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "backendServices")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "backendServices", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockBackendServicesObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAlphaBackendServiceHook defines the hook for updating an alpha BackendService.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateAlphaBackendServiceHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "alpha", "backendServices")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionAlpha, projectID, "backendServices", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockBackendServicesObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateBetaBackendServiceHook defines the hook for updating an beta BackendService.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateBetaBackendServiceHook(ctx context.Context, key *meta.Key, obj *beta.BackendService, m *cloud.MockBetaBackendServices) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "beta", "backendServices")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionBeta, projectID, "backendServices", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockBackendServicesObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateURLMapHook defines the hook for updating a UrlMap.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateURLMapHook(ctx context.Context, key *meta.Key, obj *ga.UrlMap, m *cloud.MockUrlMaps) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "urlMaps")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "urlMaps", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockUrlMapsObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertFirewallsUnauthorizedErrHook mocks firewall insertion. A forbidden error will be thrown as return.
|
||||
func InsertFirewallsUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m *cloud.MockFirewalls) (bool, error) {
|
||||
return true, &googleapi.Error{Code: http.StatusForbidden}
|
||||
}
|
||||
|
||||
// UpdateFirewallsUnauthorizedErrHook mocks firewall updating. A forbidden error will be thrown as return.
|
||||
func UpdateFirewallsUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m *cloud.MockFirewalls) error {
|
||||
return &googleapi.Error{Code: http.StatusForbidden}
|
||||
}
|
||||
|
||||
// DeleteFirewallsUnauthorizedErrHook mocks firewall deletion. A forbidden error will be thrown as return.
|
||||
func DeleteFirewallsUnauthorizedErrHook(ctx context.Context, key *meta.Key, m *cloud.MockFirewalls) (bool, error) {
|
||||
return true, &googleapi.Error{Code: http.StatusForbidden}
|
||||
}
|
||||
|
||||
// GetFirewallsUnauthorizedErrHook mocks firewall information retrival. A forbidden error will be thrown as return.
|
||||
func GetFirewallsUnauthorizedErrHook(ctx context.Context, key *meta.Key, m *cloud.MockFirewalls) (bool, *ga.Firewall, error) {
|
||||
return true, nil, &googleapi.Error{Code: http.StatusForbidden}
|
||||
}
|
||||
|
||||
// GetTargetPoolInternalErrHook mocks getting target pool. It returns a internal server error.
|
||||
func GetTargetPoolInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockTargetPools) (bool, *ga.TargetPool, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// GetForwardingRulesInternalErrHook mocks getting forwarding rules and returns an internal server error.
|
||||
func GetForwardingRulesInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockForwardingRules) (bool, *ga.ForwardingRule, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// GetAddressesInternalErrHook mocks getting network address and returns an internal server error.
|
||||
func GetAddressesInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockAddresses) (bool, *ga.Address, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// GetHTTPHealthChecksInternalErrHook mocks getting http health check and returns an internal server error.
|
||||
func GetHTTPHealthChecksInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockHttpHealthChecks) (bool, *ga.HttpHealthCheck, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// InsertTargetPoolsInternalErrHook mocks getting target pool and returns an internal server error.
|
||||
func InsertTargetPoolsInternalErrHook(ctx context.Context, key *meta.Key, obj *ga.TargetPool, m *cloud.MockTargetPools) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// InsertForwardingRulesInternalErrHook mocks getting forwarding rule and returns an internal server error.
|
||||
func InsertForwardingRulesInternalErrHook(ctx context.Context, key *meta.Key, obj *ga.ForwardingRule, m *cloud.MockForwardingRules) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// DeleteAddressesNotFoundErrHook mocks deleting network address and returns a not found error.
|
||||
func DeleteAddressesNotFoundErrHook(ctx context.Context, key *meta.Key, m *cloud.MockAddresses) (bool, error) {
|
||||
return true, &googleapi.Error{Code: http.StatusNotFound}
|
||||
}
|
||||
|
||||
// DeleteAddressesInternalErrHook mocks deleting address and returns an internal server error.
|
||||
func DeleteAddressesInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockAddresses) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// InsertAlphaBackendServiceUnauthorizedErrHook mocks inserting an alpha BackendService and returns a forbidden error.
|
||||
func InsertAlphaBackendServiceUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) (bool, error) {
|
||||
return true, UnauthorizedErr
|
||||
}
|
||||
|
||||
// UpdateAlphaBackendServiceUnauthorizedErrHook mocks updating an alpha BackendService and returns a forbidden error.
|
||||
func UpdateAlphaBackendServiceUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) error {
|
||||
return UnauthorizedErr
|
||||
}
|
||||
|
||||
// GetRegionBackendServicesErrHook mocks getting region backend service and returns an internal server error.
|
||||
func GetRegionBackendServicesErrHook(ctx context.Context, key *meta.Key, m *cloud.MockRegionBackendServices) (bool, *ga.BackendService, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// UpdateRegionBackendServicesErrHook mocks updating a reegion backend service and returns an internal server error.
|
||||
func UpdateRegionBackendServicesErrHook(ctx context.Context, key *meta.Key, svc *ga.BackendService, m *cloud.MockRegionBackendServices) error {
|
||||
return InternalServerError
|
||||
}
|
||||
|
||||
// DeleteRegionBackendServicesErrHook mocks deleting region backend service and returns an internal server error.
|
||||
func DeleteRegionBackendServicesErrHook(ctx context.Context, key *meta.Key, m *cloud.MockRegionBackendServices) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// DeleteRegionBackendServicesInUseErrHook mocks deleting region backend service and returns an InUseError.
|
||||
func DeleteRegionBackendServicesInUseErrHook(ctx context.Context, key *meta.Key, m *cloud.MockRegionBackendServices) (bool, error) {
|
||||
return true, InUseError
|
||||
}
|
||||
|
||||
// GetInstanceGroupInternalErrHook mocks getting instance group and returns an internal server error.
|
||||
func GetInstanceGroupInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockInstanceGroups) (bool, *ga.InstanceGroup, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// GetHealthChecksInternalErrHook mocks getting health check and returns an internal server erorr.
|
||||
func GetHealthChecksInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockHealthChecks) (bool, *ga.HealthCheck, error) {
|
||||
return true, nil, InternalServerError
|
||||
}
|
||||
|
||||
// DeleteHealthChecksInternalErrHook mocks deleting health check and returns an internal server error.
|
||||
func DeleteHealthChecksInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockHealthChecks) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// DeleteHealthChecksInuseErrHook mocks deleting health check and returns an in use error.
|
||||
func DeleteHealthChecksInuseErrHook(ctx context.Context, key *meta.Key, m *cloud.MockHealthChecks) (bool, error) {
|
||||
return true, InUseError
|
||||
}
|
||||
|
||||
// DeleteForwardingRuleErrHook mocks deleting forwarding rule and returns an internal server error.
|
||||
func DeleteForwardingRuleErrHook(ctx context.Context, key *meta.Key, m *cloud.MockForwardingRules) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// ListZonesInternalErrHook mocks listing zone and returns an internal server error.
|
||||
func ListZonesInternalErrHook(ctx context.Context, fl *filter.F, m *cloud.MockZones) (bool, []*ga.Zone, error) {
|
||||
return true, []*ga.Zone{}, InternalServerError
|
||||
}
|
||||
|
||||
// DeleteInstanceGroupInternalErrHook mocks deleting instance group and returns an internal server error.
|
||||
func DeleteInstanceGroupInternalErrHook(ctx context.Context, key *meta.Key, m *cloud.MockInstanceGroups) (bool, error) {
|
||||
return true, InternalServerError
|
||||
}
|
219
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/op.go
generated
vendored
Normal file
219
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/op.go
generated
vendored
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
alpha "google.golang.org/api/compute/v0.alpha"
|
||||
beta "google.golang.org/api/compute/v0.beta"
|
||||
ga "google.golang.org/api/compute/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
|
||||
)
|
||||
|
||||
const (
|
||||
operationStatusDone = "DONE"
|
||||
)
|
||||
|
||||
// operation is a GCE operation that can be watied on.
|
||||
type operation interface {
|
||||
// isDone queries GCE for the done status. This call can block.
|
||||
isDone(ctx context.Context) (bool, error)
|
||||
// error returns the resulting error of the operation. This may be nil if the operations
|
||||
// was successful.
|
||||
error() error
|
||||
// rateLimitKey returns the rate limit key to use for the given operation.
|
||||
// This rate limit will govern how fast the server will be polled for
|
||||
// operation completion status.
|
||||
rateLimitKey() *RateLimitKey
|
||||
}
|
||||
|
||||
type gaOperation struct {
|
||||
s *Service
|
||||
projectID string
|
||||
key *meta.Key
|
||||
err error
|
||||
}
|
||||
|
||||
func (o *gaOperation) String() string {
|
||||
return fmt.Sprintf("gaOperation{%q, %v}", o.projectID, o.key)
|
||||
}
|
||||
|
||||
func (o *gaOperation) isDone(ctx context.Context) (bool, error) {
|
||||
var (
|
||||
op *ga.Operation
|
||||
err error
|
||||
)
|
||||
|
||||
switch o.key.Type() {
|
||||
case meta.Regional:
|
||||
op, err = o.s.GA.RegionOperations.Get(o.projectID, o.key.Region, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("GA.RegionOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Region, o.key.Name, op, err, ctx)
|
||||
case meta.Zonal:
|
||||
op, err = o.s.GA.ZoneOperations.Get(o.projectID, o.key.Zone, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("GA.ZoneOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Zone, o.key.Name, op, err, ctx)
|
||||
case meta.Global:
|
||||
op, err = o.s.GA.GlobalOperations.Get(o.projectID, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("GA.GlobalOperations.Get(%v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Name, op, err, ctx)
|
||||
default:
|
||||
return false, fmt.Errorf("invalid key type: %#v", o.key)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if op == nil || op.Status != operationStatusDone {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if op.Error != nil && len(op.Error.Errors) > 0 && op.Error.Errors[0] != nil {
|
||||
e := op.Error.Errors[0]
|
||||
o.err = &googleapi.Error{Code: int(op.HttpErrorStatusCode), Message: fmt.Sprintf("%v - %v", e.Code, e.Message)}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (o *gaOperation) rateLimitKey() *RateLimitKey {
|
||||
return &RateLimitKey{
|
||||
ProjectID: o.projectID,
|
||||
Operation: "Get",
|
||||
Service: "Operations",
|
||||
Version: meta.VersionGA,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *gaOperation) error() error {
|
||||
return o.err
|
||||
}
|
||||
|
||||
type alphaOperation struct {
|
||||
s *Service
|
||||
projectID string
|
||||
key *meta.Key
|
||||
err error
|
||||
}
|
||||
|
||||
func (o *alphaOperation) String() string {
|
||||
return fmt.Sprintf("alphaOperation{%q, %v}", o.projectID, o.key)
|
||||
}
|
||||
|
||||
func (o *alphaOperation) isDone(ctx context.Context) (bool, error) {
|
||||
var (
|
||||
op *alpha.Operation
|
||||
err error
|
||||
)
|
||||
|
||||
switch o.key.Type() {
|
||||
case meta.Regional:
|
||||
op, err = o.s.Alpha.RegionOperations.Get(o.projectID, o.key.Region, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("Alpha.RegionOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Region, o.key.Name, op, err, ctx)
|
||||
case meta.Zonal:
|
||||
op, err = o.s.Alpha.ZoneOperations.Get(o.projectID, o.key.Zone, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("Alpha.ZoneOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Zone, o.key.Name, op, err, ctx)
|
||||
case meta.Global:
|
||||
op, err = o.s.Alpha.GlobalOperations.Get(o.projectID, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("Alpha.GlobalOperations.Get(%v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Name, op, err, ctx)
|
||||
default:
|
||||
return false, fmt.Errorf("invalid key type: %#v", o.key)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if op == nil || op.Status != operationStatusDone {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if op.Error != nil && len(op.Error.Errors) > 0 && op.Error.Errors[0] != nil {
|
||||
e := op.Error.Errors[0]
|
||||
o.err = &googleapi.Error{Code: int(op.HttpErrorStatusCode), Message: fmt.Sprintf("%v - %v", e.Code, e.Message)}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (o *alphaOperation) rateLimitKey() *RateLimitKey {
|
||||
return &RateLimitKey{
|
||||
ProjectID: o.projectID,
|
||||
Operation: "Get",
|
||||
Service: "Operations",
|
||||
Version: meta.VersionAlpha,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *alphaOperation) error() error {
|
||||
return o.err
|
||||
}
|
||||
|
||||
type betaOperation struct {
|
||||
s *Service
|
||||
projectID string
|
||||
key *meta.Key
|
||||
err error
|
||||
}
|
||||
|
||||
func (o *betaOperation) String() string {
|
||||
return fmt.Sprintf("betaOperation{%q, %v}", o.projectID, o.key)
|
||||
}
|
||||
|
||||
func (o *betaOperation) isDone(ctx context.Context) (bool, error) {
|
||||
var (
|
||||
op *beta.Operation
|
||||
err error
|
||||
)
|
||||
|
||||
switch o.key.Type() {
|
||||
case meta.Regional:
|
||||
op, err = o.s.Beta.RegionOperations.Get(o.projectID, o.key.Region, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("Beta.RegionOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Region, o.key.Name, op, err, ctx)
|
||||
case meta.Zonal:
|
||||
op, err = o.s.Beta.ZoneOperations.Get(o.projectID, o.key.Zone, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("Beta.ZoneOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Zone, o.key.Name, op, err, ctx)
|
||||
case meta.Global:
|
||||
op, err = o.s.Beta.GlobalOperations.Get(o.projectID, o.key.Name).Context(ctx).Do()
|
||||
klog.V(5).Infof("Beta.GlobalOperations.Get(%v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Name, op, err, ctx)
|
||||
default:
|
||||
return false, fmt.Errorf("invalid key type: %#v", o.key)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if op == nil || op.Status != operationStatusDone {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if op.Error != nil && len(op.Error.Errors) > 0 && op.Error.Errors[0] != nil {
|
||||
e := op.Error.Errors[0]
|
||||
o.err = &googleapi.Error{Code: int(op.HttpErrorStatusCode), Message: fmt.Sprintf("%v - %v", e.Code, e.Message)}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (o *betaOperation) rateLimitKey() *RateLimitKey {
|
||||
return &RateLimitKey{
|
||||
ProjectID: o.projectID,
|
||||
Operation: "Get",
|
||||
Service: "Operations",
|
||||
Version: meta.VersionBeta,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *betaOperation) error() error {
|
||||
return o.err
|
||||
}
|
45
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/project.go
generated
vendored
Normal file
45
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/project.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
|
||||
)
|
||||
|
||||
// ProjectRouter routes service calls to the appropriate GCE project.
|
||||
type ProjectRouter interface {
|
||||
// ProjectID returns the project ID (non-numeric) to be used for a call
|
||||
// to an API (version,service). Example tuples: ("ga", "ForwardingRules"),
|
||||
// ("alpha", "GlobalAddresses").
|
||||
//
|
||||
// This allows for plumbing different service calls to the appropriate
|
||||
// project, for instance, networking services to a separate project
|
||||
// than instance management.
|
||||
ProjectID(ctx context.Context, version meta.Version, service string) string
|
||||
}
|
||||
|
||||
// SingleProjectRouter routes all service calls to the same project ID.
|
||||
type SingleProjectRouter struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
// ProjectID returns the project ID to be used for a call to the API.
|
||||
func (r *SingleProjectRouter) ProjectID(ctx context.Context, version meta.Version, service string) string {
|
||||
return r.ID
|
||||
}
|
106
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/ratelimit.go
generated
vendored
Normal file
106
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/ratelimit.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
|
||||
)
|
||||
|
||||
// RateLimitKey is a key identifying the operation to be rate limited. The rate limit
|
||||
// queue will be determined based on the contents of RateKey.
|
||||
type RateLimitKey struct {
|
||||
// ProjectID is the non-numeric ID of the project.
|
||||
ProjectID string
|
||||
// Operation is the specific method being invoked (e.g. "Get", "List").
|
||||
Operation string
|
||||
// Version is the API version of the call.
|
||||
Version meta.Version
|
||||
// Service is the service being invoked (e.g. "Firewalls", "BackendServices")
|
||||
Service string
|
||||
}
|
||||
|
||||
// RateLimiter is the interface for a rate limiting policy.
|
||||
type RateLimiter interface {
|
||||
// Accept uses the RateLimitKey to derive a sleep time for the calling
|
||||
// goroutine. This call will block until the operation is ready for
|
||||
// execution.
|
||||
//
|
||||
// Accept returns an error if the given context ctx was canceled
|
||||
// while waiting for acceptance into the queue.
|
||||
Accept(ctx context.Context, key *RateLimitKey) error
|
||||
}
|
||||
|
||||
// acceptor is an object which blocks within Accept until a call is allowed to run.
|
||||
// Accept is a behavior of the flowcontrol.RateLimiter interface.
|
||||
type acceptor interface {
|
||||
// Accept blocks until a call is allowed to run.
|
||||
Accept()
|
||||
}
|
||||
|
||||
// AcceptRateLimiter wraps an Acceptor with RateLimiter parameters.
|
||||
type AcceptRateLimiter struct {
|
||||
// Acceptor is the underlying rate limiter.
|
||||
Acceptor acceptor
|
||||
}
|
||||
|
||||
// Accept wraps an Acceptor and blocks on Accept or context.Done(). Key is ignored.
|
||||
func (rl *AcceptRateLimiter) Accept(ctx context.Context, key *RateLimitKey) error {
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
rl.Acceptor.Accept()
|
||||
close(ch)
|
||||
}()
|
||||
select {
|
||||
case <-ch:
|
||||
break
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NopRateLimiter is a rate limiter that performs no rate limiting.
|
||||
type NopRateLimiter struct {
|
||||
}
|
||||
|
||||
// Accept everything immediately.
|
||||
func (*NopRateLimiter) Accept(ctx context.Context, key *RateLimitKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MinimumRateLimiter wraps a RateLimiter and will only call its Accept until the minimum
|
||||
// duration has been met or the context is cancelled.
|
||||
type MinimumRateLimiter struct {
|
||||
// RateLimiter is the underlying ratelimiter which is called after the mininum time is reacehd.
|
||||
RateLimiter RateLimiter
|
||||
// Minimum is the minimum wait time before the underlying ratelimiter is called.
|
||||
Minimum time.Duration
|
||||
}
|
||||
|
||||
// Accept blocks on the minimum duration and context. Once the minimum duration is met,
|
||||
// the func is blocked on the underlying ratelimiter.
|
||||
func (m *MinimumRateLimiter) Accept(ctx context.Context, key *RateLimitKey) error {
|
||||
select {
|
||||
case <-time.After(m.Minimum):
|
||||
return m.RateLimiter.Accept(ctx, key)
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
110
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/service.go
generated
vendored
Normal file
110
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/service.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
alpha "google.golang.org/api/compute/v0.alpha"
|
||||
beta "google.golang.org/api/compute/v0.beta"
|
||||
ga "google.golang.org/api/compute/v1"
|
||||
)
|
||||
|
||||
// Service is the top-level adapter for all of the different compute API
|
||||
// versions.
|
||||
type Service struct {
|
||||
GA *ga.Service
|
||||
Alpha *alpha.Service
|
||||
Beta *beta.Service
|
||||
ProjectRouter ProjectRouter
|
||||
RateLimiter RateLimiter
|
||||
}
|
||||
|
||||
// wrapOperation wraps a GCE anyOP in a version generic operation type.
|
||||
func (s *Service) wrapOperation(anyOp interface{}) (operation, error) {
|
||||
switch o := anyOp.(type) {
|
||||
case *ga.Operation:
|
||||
r, err := ParseResourceURL(o.SelfLink)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &gaOperation{s: s, projectID: r.ProjectID, key: r.Key}, nil
|
||||
case *alpha.Operation:
|
||||
r, err := ParseResourceURL(o.SelfLink)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &alphaOperation{s: s, projectID: r.ProjectID, key: r.Key}, nil
|
||||
case *beta.Operation:
|
||||
r, err := ParseResourceURL(o.SelfLink)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &betaOperation{s: s, projectID: r.ProjectID, key: r.Key}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid type %T", anyOp)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForCompletion of a long running operation. This will poll the state of
|
||||
// GCE for the completion status of the given operation. genericOp can be one
|
||||
// of alpha, beta, ga Operation types.
|
||||
func (s *Service) WaitForCompletion(ctx context.Context, genericOp interface{}) error {
|
||||
op, err := s.wrapOperation(genericOp)
|
||||
if err != nil {
|
||||
klog.Errorf("wrapOperation(%+v) error: %v", genericOp, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return s.pollOperation(ctx, op)
|
||||
}
|
||||
|
||||
// pollOperation calls operations.isDone until the function comes back true or context is Done.
|
||||
// If an error occurs retrieving the operation, the loop will continue until the context is done.
|
||||
// This is to prevent a transient error from bubbling up to controller-level logic.
|
||||
func (s *Service) pollOperation(ctx context.Context, op operation) error {
|
||||
var pollCount int
|
||||
for {
|
||||
// Check if context has been cancelled. Note that ctx.Done() must be checked before
|
||||
// returning ctx.Err().
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
klog.V(5).Infof("op.pollOperation(%v, %v) not completed, poll count = %d, ctx.Err = %v", ctx, op, pollCount, ctx.Err())
|
||||
return ctx.Err()
|
||||
default:
|
||||
// ctx is not canceled, continue immediately
|
||||
}
|
||||
|
||||
pollCount++
|
||||
klog.V(5).Infof("op.isDone(%v) waiting; op = %v, poll count = %d", ctx, op, pollCount)
|
||||
s.RateLimiter.Accept(ctx, op.rateLimitKey())
|
||||
done, err := op.isDone(ctx)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("op.isDone(%v) error; op = %v, poll count = %d, err = %v, retrying", ctx, op, pollCount, err)
|
||||
}
|
||||
|
||||
if done {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(5).Infof("op.isDone(%v) complete; op = %v, poll count = %d, op.err = %v", ctx, op, pollCount, op.error())
|
||||
return op.error()
|
||||
}
|
201
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/utils.go
generated
vendored
Normal file
201
vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/utils.go
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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
|
||||
|
||||
https://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 cloud
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
|
||||
)
|
||||
|
||||
const (
|
||||
gaPrefix = "https://www.googleapis.com/compute/v1"
|
||||
alphaPrefix = "https://www.googleapis.com/compute/alpha"
|
||||
betaPrefix = "https://www.googleapis.com/compute/beta"
|
||||
)
|
||||
|
||||
// ResourceID identifies a GCE resource as parsed from compute resource URL.
|
||||
type ResourceID struct {
|
||||
ProjectID string
|
||||
Resource string
|
||||
Key *meta.Key
|
||||
}
|
||||
|
||||
// Equal returns true if two resource IDs are equal.
|
||||
func (r *ResourceID) Equal(other *ResourceID) bool {
|
||||
if r.ProjectID != other.ProjectID || r.Resource != other.Resource {
|
||||
return false
|
||||
}
|
||||
if r.Key != nil && other.Key != nil {
|
||||
return *r.Key == *other.Key
|
||||
}
|
||||
if r.Key == nil && other.Key == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RelativeResourceName returns the relative resource name string
|
||||
// representing this ResourceID.
|
||||
func (r *ResourceID) RelativeResourceName() string {
|
||||
return RelativeResourceName(r.ProjectID, r.Resource, r.Key)
|
||||
}
|
||||
|
||||
// ResourcePath returns the resource path representing this ResourceID.
|
||||
func (r *ResourceID) ResourcePath() string {
|
||||
return ResourcePath(r.Resource, r.Key)
|
||||
}
|
||||
|
||||
func (r *ResourceID) SelfLink(ver meta.Version) string {
|
||||
return SelfLink(ver, r.ProjectID, r.Resource, r.Key)
|
||||
}
|
||||
|
||||
// ParseResourceURL parses resource URLs of the following formats:
|
||||
//
|
||||
// global/<res>/<name>
|
||||
// regions/<region>/<res>/<name>
|
||||
// zones/<zone>/<res>/<name>
|
||||
// projects/<proj>
|
||||
// projects/<proj>/global/<res>/<name>
|
||||
// projects/<proj>/regions/<region>/<res>/<name>
|
||||
// projects/<proj>/zones/<zone>/<res>/<name>
|
||||
// [https://www.googleapis.com/compute/<ver>]/projects/<proj>/global/<res>/<name>
|
||||
// [https://www.googleapis.com/compute/<ver>]/projects/<proj>/regions/<region>/<res>/<name>
|
||||
// [https://www.googleapis.com/compute/<ver>]/projects/<proj>/zones/<zone>/<res>/<name>
|
||||
func ParseResourceURL(url string) (*ResourceID, error) {
|
||||
errNotValid := fmt.Errorf("%q is not a valid resource URL", url)
|
||||
|
||||
// Trim prefix off URL leaving "projects/..."
|
||||
projectsIndex := strings.Index(url, "/projects/")
|
||||
if projectsIndex >= 0 {
|
||||
url = url[projectsIndex+1:]
|
||||
}
|
||||
|
||||
parts := strings.Split(url, "/")
|
||||
if len(parts) < 2 || len(parts) > 6 {
|
||||
return nil, errNotValid
|
||||
}
|
||||
|
||||
ret := &ResourceID{}
|
||||
scopedName := parts
|
||||
if parts[0] == "projects" {
|
||||
ret.Resource = "projects"
|
||||
ret.ProjectID = parts[1]
|
||||
scopedName = parts[2:]
|
||||
|
||||
if len(scopedName) == 0 {
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
switch scopedName[0] {
|
||||
case "global":
|
||||
if len(scopedName) != 3 {
|
||||
return nil, errNotValid
|
||||
}
|
||||
ret.Resource = scopedName[1]
|
||||
ret.Key = meta.GlobalKey(scopedName[2])
|
||||
return ret, nil
|
||||
case "regions":
|
||||
switch len(scopedName) {
|
||||
case 2:
|
||||
ret.Resource = "regions"
|
||||
ret.Key = meta.GlobalKey(scopedName[1])
|
||||
return ret, nil
|
||||
case 4:
|
||||
ret.Resource = scopedName[2]
|
||||
ret.Key = meta.RegionalKey(scopedName[3], scopedName[1])
|
||||
return ret, nil
|
||||
default:
|
||||
return nil, errNotValid
|
||||
}
|
||||
case "zones":
|
||||
switch len(scopedName) {
|
||||
case 2:
|
||||
ret.Resource = "zones"
|
||||
ret.Key = meta.GlobalKey(scopedName[1])
|
||||
return ret, nil
|
||||
case 4:
|
||||
ret.Resource = scopedName[2]
|
||||
ret.Key = meta.ZonalKey(scopedName[3], scopedName[1])
|
||||
return ret, nil
|
||||
default:
|
||||
return nil, errNotValid
|
||||
}
|
||||
}
|
||||
return nil, errNotValid
|
||||
}
|
||||
|
||||
func copyViaJSON(dest, src interface{}) error {
|
||||
bytes, err := json.Marshal(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(bytes, dest)
|
||||
}
|
||||
|
||||
// ResourcePath returns the path starting from the location.
|
||||
// Example: regions/us-central1/subnetworks/my-subnet
|
||||
func ResourcePath(resource string, key *meta.Key) string {
|
||||
switch resource {
|
||||
case "zones", "regions":
|
||||
return fmt.Sprintf("%s/%s", resource, key.Name)
|
||||
case "projects":
|
||||
return "invalid-resource"
|
||||
}
|
||||
|
||||
switch key.Type() {
|
||||
case meta.Zonal:
|
||||
return fmt.Sprintf("zones/%s/%s/%s", key.Zone, resource, key.Name)
|
||||
case meta.Regional:
|
||||
return fmt.Sprintf("regions/%s/%s/%s", key.Region, resource, key.Name)
|
||||
case meta.Global:
|
||||
return fmt.Sprintf("global/%s/%s", resource, key.Name)
|
||||
}
|
||||
return "invalid-key-type"
|
||||
}
|
||||
|
||||
// RelativeResourceName returns the path starting from project.
|
||||
// Example: projects/my-project/regions/us-central1/subnetworks/my-subnet
|
||||
func RelativeResourceName(project, resource string, key *meta.Key) string {
|
||||
switch resource {
|
||||
case "projects":
|
||||
return fmt.Sprintf("projects/%s", project)
|
||||
default:
|
||||
return fmt.Sprintf("projects/%s/%s", project, ResourcePath(resource, key))
|
||||
}
|
||||
}
|
||||
|
||||
// SelfLink returns the self link URL for the given object.
|
||||
func SelfLink(ver meta.Version, project, resource string, key *meta.Key) string {
|
||||
var prefix string
|
||||
switch ver {
|
||||
case meta.VersionAlpha:
|
||||
prefix = alphaPrefix
|
||||
case meta.VersionBeta:
|
||||
prefix = betaPrefix
|
||||
case meta.VersionGA:
|
||||
prefix = gaPrefix
|
||||
default:
|
||||
prefix = "invalid-prefix"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", prefix, RelativeResourceName(project, resource, key))
|
||||
|
||||
}
|
Loading…
Reference in New Issue