mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-16 23:29:21 +00:00
Expand ability of ResourceID
This commit is contained in:
parent
d39ff8e651
commit
8098b91951
@ -13152,3 +13152,147 @@ func (g *GCEZones) List(ctx context.Context, fl *filter.F) ([]*ga.Zone, error) {
|
|||||||
|
|
||||||
return all, nil
|
return all, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewAddressesResourceID creates a ResourceID for the Addresses resource.
|
||||||
|
func NewAddressesResourceID(project, region, name string) *ResourceID {
|
||||||
|
key := meta.RegionalKey(name, region)
|
||||||
|
return &ResourceID{project, "addresses", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBackendServicesResourceID creates a ResourceID for the BackendServices resource.
|
||||||
|
func NewBackendServicesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "backendServices", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDisksResourceID creates a ResourceID for the Disks resource.
|
||||||
|
func NewDisksResourceID(project, zone, name string) *ResourceID {
|
||||||
|
key := meta.ZonalKey(name, zone)
|
||||||
|
return &ResourceID{project, "disks", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFirewallsResourceID creates a ResourceID for the Firewalls resource.
|
||||||
|
func NewFirewallsResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "firewalls", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewForwardingRulesResourceID creates a ResourceID for the ForwardingRules resource.
|
||||||
|
func NewForwardingRulesResourceID(project, region, name string) *ResourceID {
|
||||||
|
key := meta.RegionalKey(name, region)
|
||||||
|
return &ResourceID{project, "forwardingRules", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGlobalAddressesResourceID creates a ResourceID for the GlobalAddresses resource.
|
||||||
|
func NewGlobalAddressesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "addresses", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGlobalForwardingRulesResourceID creates a ResourceID for the GlobalForwardingRules resource.
|
||||||
|
func NewGlobalForwardingRulesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "forwardingRules", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHealthChecksResourceID creates a ResourceID for the HealthChecks resource.
|
||||||
|
func NewHealthChecksResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "healthChecks", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHttpHealthChecksResourceID creates a ResourceID for the HttpHealthChecks resource.
|
||||||
|
func NewHttpHealthChecksResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "httpHealthChecks", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHttpsHealthChecksResourceID creates a ResourceID for the HttpsHealthChecks resource.
|
||||||
|
func NewHttpsHealthChecksResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "httpsHealthChecks", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInstanceGroupsResourceID creates a ResourceID for the InstanceGroups resource.
|
||||||
|
func NewInstanceGroupsResourceID(project, zone, name string) *ResourceID {
|
||||||
|
key := meta.ZonalKey(name, zone)
|
||||||
|
return &ResourceID{project, "instanceGroups", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInstancesResourceID creates a ResourceID for the Instances resource.
|
||||||
|
func NewInstancesResourceID(project, zone, name string) *ResourceID {
|
||||||
|
key := meta.ZonalKey(name, zone)
|
||||||
|
return &ResourceID{project, "instances", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetworkEndpointGroupsResourceID creates a ResourceID for the NetworkEndpointGroups resource.
|
||||||
|
func NewNetworkEndpointGroupsResourceID(project, zone, name string) *ResourceID {
|
||||||
|
key := meta.ZonalKey(name, zone)
|
||||||
|
return &ResourceID{project, "networkEndpointGroups", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProjectsResourceID creates a ResourceID for the Projects resource.
|
||||||
|
func NewProjectsResourceID(project string) *ResourceID {
|
||||||
|
var key *meta.Key
|
||||||
|
return &ResourceID{project, "projects", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRegionBackendServicesResourceID creates a ResourceID for the RegionBackendServices resource.
|
||||||
|
func NewRegionBackendServicesResourceID(project, region, name string) *ResourceID {
|
||||||
|
key := meta.RegionalKey(name, region)
|
||||||
|
return &ResourceID{project, "backendServices", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRegionDisksResourceID creates a ResourceID for the RegionDisks resource.
|
||||||
|
func NewRegionDisksResourceID(project, region, name string) *ResourceID {
|
||||||
|
key := meta.RegionalKey(name, region)
|
||||||
|
return &ResourceID{project, "disks", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRegionsResourceID creates a ResourceID for the Regions resource.
|
||||||
|
func NewRegionsResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "regions", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRoutesResourceID creates a ResourceID for the Routes resource.
|
||||||
|
func NewRoutesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "routes", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSslCertificatesResourceID creates a ResourceID for the SslCertificates resource.
|
||||||
|
func NewSslCertificatesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "sslCertificates", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTargetHttpProxiesResourceID creates a ResourceID for the TargetHttpProxies resource.
|
||||||
|
func NewTargetHttpProxiesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "targetHttpProxies", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTargetHttpsProxiesResourceID creates a ResourceID for the TargetHttpsProxies resource.
|
||||||
|
func NewTargetHttpsProxiesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "targetHttpsProxies", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTargetPoolsResourceID creates a ResourceID for the TargetPools resource.
|
||||||
|
func NewTargetPoolsResourceID(project, region, name string) *ResourceID {
|
||||||
|
key := meta.RegionalKey(name, region)
|
||||||
|
return &ResourceID{project, "targetPools", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUrlMapsResourceID creates a ResourceID for the UrlMaps resource.
|
||||||
|
func NewUrlMapsResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "urlMaps", key}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewZonesResourceID creates a ResourceID for the Zones resource.
|
||||||
|
func NewZonesResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
return &ResourceID{project, "zones", key}
|
||||||
|
}
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sort"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -986,6 +985,38 @@ func (g *{{.GCEWrapType}}) {{.FcnArgs}} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// genTypes generates the type wrappers.
|
||||||
|
func genResourceIDs(wr io.Writer) {
|
||||||
|
const text = `
|
||||||
|
// New{{.Service}}ResourceID creates a ResourceID for the {{.Service}} resource.
|
||||||
|
{{- if .KeyIsProject}}
|
||||||
|
func New{{.Service}}ResourceID(project string) *ResourceID {
|
||||||
|
var key *meta.Key
|
||||||
|
{{- else}}
|
||||||
|
{{- if .KeyIsGlobal}}
|
||||||
|
func New{{.Service}}ResourceID(project, name string) *ResourceID {
|
||||||
|
key := meta.GlobalKey(name)
|
||||||
|
{{- end}}
|
||||||
|
{{- if .KeyIsRegional}}
|
||||||
|
func New{{.Service}}ResourceID(project, region, name string) *ResourceID {
|
||||||
|
key := meta.RegionalKey(name, region)
|
||||||
|
{{- end}}
|
||||||
|
{{- if .KeyIsZonal}}
|
||||||
|
func New{{.Service}}ResourceID(project, zone, name string) *ResourceID {
|
||||||
|
key := meta.ZonalKey(name, zone)
|
||||||
|
{{- end -}}
|
||||||
|
{{end}}
|
||||||
|
return &ResourceID{project, "{{.Resource}}", key}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
tmpl := template.Must(template.New("resourceIDs").Parse(text))
|
||||||
|
for _, sg := range meta.SortedServicesGroups {
|
||||||
|
if err := tmpl.Execute(wr, sg.ServiceInfo()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func genUnitTestHeader(wr io.Writer) {
|
func genUnitTestHeader(wr io.Writer) {
|
||||||
const text = `/*
|
const text = `/*
|
||||||
Copyright {{.Year}} The Kubernetes Authors.
|
Copyright {{.Year}} The Kubernetes Authors.
|
||||||
@ -1238,20 +1269,86 @@ func Test{{.Service}}Group(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
tmpl := template.Must(template.New("unittest").Parse(text))
|
tmpl := template.Must(template.New("unittest").Parse(text))
|
||||||
// Sort keys so the output will be stable.
|
for _, sg := range meta.SortedServicesGroups {
|
||||||
var keys []string
|
if err := tmpl.Execute(wr, sg); err != nil {
|
||||||
for k := range meta.AllServicesByGroup {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
for _, k := range keys {
|
|
||||||
s := meta.AllServicesByGroup[k]
|
|
||||||
if err := tmpl.Execute(wr, s); err != nil {
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func genUnitTestResourceIDConversion(wr io.Writer) {
|
||||||
|
const text = `
|
||||||
|
func TestResourceIDConversion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, id := range []*ResourceID{
|
||||||
|
{{- range .Groups}}
|
||||||
|
{{- with .ServiceInfo}}
|
||||||
|
{{- if .KeyIsProject}}
|
||||||
|
New{{.Service}}ResourceID("my-{{.Resource}}-resource"),
|
||||||
|
{{- else}}
|
||||||
|
{{- if .KeyIsGlobal}}
|
||||||
|
New{{.Service}}ResourceID("some-project", "my-{{.Resource}}-resource"),
|
||||||
|
{{- end}}
|
||||||
|
{{- if .KeyIsRegional}}
|
||||||
|
New{{.Service}}ResourceID("some-project", "us-central1", "my-{{.Resource}}-resource"),
|
||||||
|
{{- end}}
|
||||||
|
{{- if .KeyIsZonal}}
|
||||||
|
New{{.Service}}ResourceID("some-project", "us-east1-b", "my-{{.Resource}}-resource"),
|
||||||
|
{{- end -}}
|
||||||
|
{{end -}}
|
||||||
|
{{end -}}
|
||||||
|
{{end}}
|
||||||
|
} {
|
||||||
|
t.Run(id.Resource, func(t *testing.T) {
|
||||||
|
// Test conversion to and from full URL.
|
||||||
|
fullURL := id.SelfLink(meta.VersionGA)
|
||||||
|
parsedID, err := ParseResourceURL(fullURL)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", fullURL, err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(id, parsedID) {
|
||||||
|
t.Errorf("SelfLink(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, fullURL, parsedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test conversion to and from relative resource name.
|
||||||
|
relativeName := id.RelativeResourceName()
|
||||||
|
parsedID, err = ParseResourceURL(relativeName)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", relativeName, err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(id, parsedID) {
|
||||||
|
t.Errorf("RelativeResourceName(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, relativeName, parsedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not test ResourcePath for projects.
|
||||||
|
if id.Resource == "projects" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test conversion to and from resource path.
|
||||||
|
resourcePath := id.ResourcePath()
|
||||||
|
parsedID, err = ParseResourceURL(resourcePath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", resourcePath, err)
|
||||||
|
}
|
||||||
|
id.ProjectID = ""
|
||||||
|
if !reflect.DeepEqual(id, parsedID) {
|
||||||
|
t.Errorf("ResourcePath(%+v) -> ParseResourceURL(%s) = %+v, want %+v", id, resourcePath, parsedID, id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
data := struct {
|
||||||
|
Groups []*meta.ServiceGroup
|
||||||
|
}{meta.SortedServicesGroups}
|
||||||
|
tmpl := template.Must(template.New("unittest-resourceIDs").Parse(text))
|
||||||
|
if err := tmpl.Execute(wr, data); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@ -1262,9 +1359,11 @@ func main() {
|
|||||||
genHeader(out)
|
genHeader(out)
|
||||||
genStubs(out)
|
genStubs(out)
|
||||||
genTypes(out)
|
genTypes(out)
|
||||||
|
genResourceIDs(out)
|
||||||
case "test":
|
case "test":
|
||||||
genUnitTestHeader(out)
|
genUnitTestHeader(out)
|
||||||
genUnitTestServices(out)
|
genUnitTestServices(out)
|
||||||
|
genUnitTestResourceIDConversion(out)
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Invalid -mode: %q", flags.mode)
|
log.Fatalf("Invalid -mode: %q", flags.mode)
|
||||||
}
|
}
|
||||||
|
@ -1807,3 +1807,72 @@ func TestZonesGroup(t *testing.T) {
|
|||||||
|
|
||||||
// Delete not found.
|
// Delete not found.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResourceIDConversion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, id := range []*ResourceID{
|
||||||
|
NewAddressesResourceID("some-project", "us-central1", "my-addresses-resource"),
|
||||||
|
NewBackendServicesResourceID("some-project", "my-backendServices-resource"),
|
||||||
|
NewDisksResourceID("some-project", "us-east1-b", "my-disks-resource"),
|
||||||
|
NewFirewallsResourceID("some-project", "my-firewalls-resource"),
|
||||||
|
NewForwardingRulesResourceID("some-project", "us-central1", "my-forwardingRules-resource"),
|
||||||
|
NewGlobalAddressesResourceID("some-project", "my-addresses-resource"),
|
||||||
|
NewGlobalForwardingRulesResourceID("some-project", "my-forwardingRules-resource"),
|
||||||
|
NewHealthChecksResourceID("some-project", "my-healthChecks-resource"),
|
||||||
|
NewHttpHealthChecksResourceID("some-project", "my-httpHealthChecks-resource"),
|
||||||
|
NewHttpsHealthChecksResourceID("some-project", "my-httpsHealthChecks-resource"),
|
||||||
|
NewInstanceGroupsResourceID("some-project", "us-east1-b", "my-instanceGroups-resource"),
|
||||||
|
NewInstancesResourceID("some-project", "us-east1-b", "my-instances-resource"),
|
||||||
|
NewNetworkEndpointGroupsResourceID("some-project", "us-east1-b", "my-networkEndpointGroups-resource"),
|
||||||
|
NewProjectsResourceID("my-projects-resource"),
|
||||||
|
NewRegionBackendServicesResourceID("some-project", "us-central1", "my-backendServices-resource"),
|
||||||
|
NewRegionDisksResourceID("some-project", "us-central1", "my-disks-resource"),
|
||||||
|
NewRegionsResourceID("some-project", "my-regions-resource"),
|
||||||
|
NewRoutesResourceID("some-project", "my-routes-resource"),
|
||||||
|
NewSslCertificatesResourceID("some-project", "my-sslCertificates-resource"),
|
||||||
|
NewTargetHttpProxiesResourceID("some-project", "my-targetHttpProxies-resource"),
|
||||||
|
NewTargetHttpsProxiesResourceID("some-project", "my-targetHttpsProxies-resource"),
|
||||||
|
NewTargetPoolsResourceID("some-project", "us-central1", "my-targetPools-resource"),
|
||||||
|
NewUrlMapsResourceID("some-project", "my-urlMaps-resource"),
|
||||||
|
NewZonesResourceID("some-project", "my-zones-resource"),
|
||||||
|
} {
|
||||||
|
t.Run(id.Resource, func(t *testing.T) {
|
||||||
|
// Test conversion to and from full URL.
|
||||||
|
fullURL := id.SelfLink(meta.VersionGA)
|
||||||
|
parsedID, err := ParseResourceURL(fullURL)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", fullURL, err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(id, parsedID) {
|
||||||
|
t.Errorf("SelfLink(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, fullURL, parsedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test conversion to and from relative resource name.
|
||||||
|
relativeName := id.RelativeResourceName()
|
||||||
|
parsedID, err = ParseResourceURL(relativeName)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", relativeName, err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(id, parsedID) {
|
||||||
|
t.Errorf("RelativeResourceName(%+v) -> ParseResourceURL(%s) = %+v, want original ID", id, relativeName, parsedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not test ResourcePath for projects.
|
||||||
|
if id.Resource == "projects" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test conversion to and from resource path.
|
||||||
|
resourcePath := id.ResourcePath()
|
||||||
|
parsedID, err = ParseResourceURL(resourcePath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParseResourceURL(%s) = _, %v, want nil", resourcePath, err)
|
||||||
|
}
|
||||||
|
id.ProjectID = ""
|
||||||
|
if !reflect.DeepEqual(id, parsedID) {
|
||||||
|
t.Errorf("ResourcePath(%+v) -> ParseResourceURL(%s) = %+v, want %+v", id, resourcePath, parsedID, id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceInfo defines the entry for a Service that code will be generated for.
|
// ServiceInfo defines the entry for a Service that code will be generated for.
|
||||||
@ -159,6 +160,13 @@ func (i *ServiceInfo) KeyIsZonal() bool {
|
|||||||
return i.keyType == Zonal
|
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.
|
// MakeKey returns the call used to create the appropriate key type.
|
||||||
func (i *ServiceInfo) MakeKey(name, location string) string {
|
func (i *ServiceInfo) MakeKey(name, location string) string {
|
||||||
switch i.keyType {
|
switch i.keyType {
|
||||||
@ -220,15 +228,20 @@ type ServiceGroup struct {
|
|||||||
GA *ServiceInfo
|
GA *ServiceInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service returns any ServiceInfo object belonging to the ServiceGroup.
|
// Service returns any ServiceInfo string belonging to the ServiceGroup.
|
||||||
func (sg *ServiceGroup) Service() string {
|
func (sg *ServiceGroup) Service() string {
|
||||||
|
return sg.ServiceInfo().Service
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceInfo returns any ServiceInfo object belonging to the ServiceGroup.
|
||||||
|
func (sg *ServiceGroup) ServiceInfo() *ServiceInfo {
|
||||||
switch {
|
switch {
|
||||||
case sg.GA != nil:
|
case sg.GA != nil:
|
||||||
return sg.GA.Service
|
return sg.GA
|
||||||
case sg.Alpha != nil:
|
case sg.Alpha != nil:
|
||||||
return sg.Alpha.Service
|
return sg.Alpha
|
||||||
case sg.Beta != nil:
|
case sg.Beta != nil:
|
||||||
return sg.Beta.Service
|
return sg.Beta
|
||||||
default:
|
default:
|
||||||
panic(errors.New("service group is empty"))
|
panic(errors.New("service group is empty"))
|
||||||
}
|
}
|
||||||
@ -272,6 +285,16 @@ func groupServices(services []*ServiceInfo) map[string]*ServiceGroup {
|
|||||||
// AllServicesByGroup is a map of service name to ServicesGroup.
|
// AllServicesByGroup is a map of service name to ServicesGroup.
|
||||||
var AllServicesByGroup map[string]*ServiceGroup
|
var AllServicesByGroup map[string]*ServiceGroup
|
||||||
|
|
||||||
|
// SortedServicesGroups is a slice of Servicegroup sorted by Service name.
|
||||||
|
var SortedServicesGroups []*ServiceGroup
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
AllServicesByGroup = groupServices(AllServices)
|
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()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
gaPrefix = "https://www.googleapis.com/compute/v1/"
|
gaPrefix = "https://www.googleapis.com/compute/v1"
|
||||||
alphaPrefix = "https://www.googleapis.com/compute/alpha/"
|
alphaPrefix = "https://www.googleapis.com/compute/alpha"
|
||||||
betaPrefix = "https://www.googleapis.com/compute/beta/"
|
betaPrefix = "https://www.googleapis.com/compute/beta"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResourceID identifies a GCE resource as parsed from compute resource URL.
|
// ResourceID identifies a GCE resource as parsed from compute resource URL.
|
||||||
@ -51,8 +51,27 @@ func (r *ResourceID) Equal(other *ResourceID) bool {
|
|||||||
return false
|
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:
|
// 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>/global/<res>/<name>
|
||||||
// projects/<proj>/regions/<region>/<res>/<name>
|
// projects/<proj>/regions/<region>/<res>/<name>
|
||||||
// projects/<proj>/zones/<zone>/<res>/<name>
|
// projects/<proj>/zones/<zone>/<res>/<name>
|
||||||
@ -62,64 +81,63 @@ func (r *ResourceID) Equal(other *ResourceID) bool {
|
|||||||
func ParseResourceURL(url string) (*ResourceID, error) {
|
func ParseResourceURL(url string) (*ResourceID, error) {
|
||||||
errNotValid := fmt.Errorf("%q is not a valid resource URL", url)
|
errNotValid := fmt.Errorf("%q is not a valid resource URL", url)
|
||||||
|
|
||||||
// Remove the prefix up to ...projects/
|
// Trim prefix off URL leaving "projects/..."
|
||||||
projectsIndex := strings.Index(url, "/projects/")
|
projectsIndex := strings.Index(url, "/projects/")
|
||||||
if projectsIndex >= 0 {
|
if projectsIndex >= 0 {
|
||||||
url = url[projectsIndex+1:]
|
url = url[projectsIndex+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
parts := strings.Split(url, "/")
|
parts := strings.Split(url, "/")
|
||||||
if len(parts) < 2 || parts[0] != "projects" {
|
if len(parts) < 2 || len(parts) > 6 {
|
||||||
return nil, errNotValid
|
return nil, errNotValid
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := &ResourceID{ProjectID: parts[1]}
|
ret := &ResourceID{}
|
||||||
if len(parts) == 2 {
|
scopedName := parts
|
||||||
|
if parts[0] == "projects" {
|
||||||
ret.Resource = "projects"
|
ret.Resource = "projects"
|
||||||
return ret, nil
|
ret.ProjectID = parts[1]
|
||||||
}
|
scopedName = parts[2:]
|
||||||
|
|
||||||
if len(parts) < 4 {
|
if len(scopedName) == 0 {
|
||||||
return nil, errNotValid
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(parts) == 4 {
|
|
||||||
switch parts[2] {
|
|
||||||
case "regions":
|
|
||||||
ret.Resource = "regions"
|
|
||||||
ret.Key = meta.GlobalKey(parts[3])
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
case "zones":
|
}
|
||||||
ret.Resource = "zones"
|
}
|
||||||
ret.Key = meta.GlobalKey(parts[3])
|
|
||||||
|
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
|
return ret, nil
|
||||||
default:
|
default:
|
||||||
return nil, errNotValid
|
return nil, errNotValid
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch parts[2] {
|
|
||||||
case "global":
|
|
||||||
if len(parts) != 5 {
|
|
||||||
return nil, errNotValid
|
|
||||||
}
|
|
||||||
ret.Resource = parts[3]
|
|
||||||
ret.Key = meta.GlobalKey(parts[4])
|
|
||||||
return ret, nil
|
|
||||||
case "regions":
|
|
||||||
if len(parts) != 6 {
|
|
||||||
return nil, errNotValid
|
|
||||||
}
|
|
||||||
ret.Resource = parts[4]
|
|
||||||
ret.Key = meta.RegionalKey(parts[5], parts[3])
|
|
||||||
return ret, nil
|
|
||||||
case "zones":
|
case "zones":
|
||||||
if len(parts) != 6 {
|
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
|
||||||
}
|
}
|
||||||
ret.Resource = parts[4]
|
|
||||||
ret.Key = meta.ZonalKey(parts[5], parts[3])
|
|
||||||
return ret, nil
|
|
||||||
}
|
}
|
||||||
return nil, errNotValid
|
return nil, errNotValid
|
||||||
}
|
}
|
||||||
@ -132,6 +150,38 @@ func copyViaJSON(dest, src interface{}) error {
|
|||||||
return json.Unmarshal(bytes, dest)
|
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.
|
// SelfLink returns the self link URL for the given object.
|
||||||
func SelfLink(ver meta.Version, project, resource string, key *meta.Key) string {
|
func SelfLink(ver meta.Version, project, resource string, key *meta.Key) string {
|
||||||
var prefix string
|
var prefix string
|
||||||
@ -146,13 +196,6 @@ func SelfLink(ver meta.Version, project, resource string, key *meta.Key) string
|
|||||||
prefix = "invalid-prefix"
|
prefix = "invalid-prefix"
|
||||||
}
|
}
|
||||||
|
|
||||||
switch key.Type() {
|
return fmt.Sprintf("%s/%s", prefix, RelativeResourceName(project, resource, key))
|
||||||
case meta.Zonal:
|
|
||||||
return fmt.Sprintf("%sprojects/%s/zones/%s/%s/%s", prefix, project, key.Zone, resource, key.Name)
|
|
||||||
case meta.Regional:
|
|
||||||
return fmt.Sprintf("%sprojects/%s/regions/%s/%s/%s", prefix, project, key.Region, resource, key.Name)
|
|
||||||
case meta.Global:
|
|
||||||
return fmt.Sprintf("%sprojects/%s/%s/%s", prefix, project, resource, key.Name)
|
|
||||||
}
|
|
||||||
return "invalid-self-link"
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,54 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
|
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestEqualResourceID(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, tc := range []struct {
|
||||||
|
a *ResourceID
|
||||||
|
b *ResourceID
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
a: &ResourceID{"some-gce-project", "projects", nil},
|
||||||
|
b: &ResourceID{"some-gce-project", "projects", nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
a: &ResourceID{"", "networks", meta.GlobalKey("my-net")},
|
||||||
|
b: &ResourceID{"", "networks", meta.GlobalKey("my-net")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
a: &ResourceID{"some-gce-project", "projects", meta.GlobalKey("us-central1")},
|
||||||
|
b: &ResourceID{"some-gce-project", "projects", meta.GlobalKey("us-central1")},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
if !tc.a.Equal(tc.b) {
|
||||||
|
t.Errorf("%v.Equal(%v) = false, want true", tc.a, tc.b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range []struct {
|
||||||
|
a *ResourceID
|
||||||
|
b *ResourceID
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
a: &ResourceID{"some-gce-project", "projects", nil},
|
||||||
|
b: &ResourceID{"some-other-project", "projects", nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
a: &ResourceID{"some-gce-project", "projects", nil},
|
||||||
|
b: &ResourceID{"some-gce-project", "projects", meta.GlobalKey("us-central1")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
a: &ResourceID{"some-gce-project", "networks", meta.GlobalKey("us-central1")},
|
||||||
|
b: &ResourceID{"some-gce-project", "projects", meta.GlobalKey("us-central1")},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
if tc.a.Equal(tc.b) {
|
||||||
|
t.Errorf("%v.Equal(%v) = true, want false", tc.a, tc.b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseResourceURL(t *testing.T) {
|
func TestParseResourceURL(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@ -90,6 +138,18 @@ func TestParseResourceURL(t *testing.T) {
|
|||||||
"projects/some-gce-project/zones/us-central1-c/instances/instance-1",
|
"projects/some-gce-project/zones/us-central1-c/instances/instance-1",
|
||||||
&ResourceID{"some-gce-project", "instances", meta.ZonalKey("instance-1", "us-central1-c")},
|
&ResourceID{"some-gce-project", "instances", meta.ZonalKey("instance-1", "us-central1-c")},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"global/networks/my-network",
|
||||||
|
&ResourceID{"", "networks", meta.GlobalKey("my-network")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"regions/us-central1/subnetworks/my-subnet",
|
||||||
|
&ResourceID{"", "subnetworks", meta.RegionalKey("my-subnet", "us-central1")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"zones/us-central1-c/instances/instance-1",
|
||||||
|
&ResourceID{"", "instances", meta.ZonalKey("instance-1", "us-central1-c")},
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
r, err := ParseResourceURL(tc.in)
|
r, err := ParseResourceURL(tc.in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -112,7 +172,9 @@ func TestParseResourceURL(t *testing.T) {
|
|||||||
"/a/b/c/d/e/f",
|
"/a/b/c/d/e/f",
|
||||||
"https://www.googleapis.com/compute/v1/projects/some-gce-project/global",
|
"https://www.googleapis.com/compute/v1/projects/some-gce-project/global",
|
||||||
"projects/some-gce-project/global",
|
"projects/some-gce-project/global",
|
||||||
|
"projects/some-gce-project/global/foo",
|
||||||
"projects/some-gce-project/global/foo/bar/baz",
|
"projects/some-gce-project/global/foo/bar/baz",
|
||||||
|
"projects/some-gce-project/regions/us-central1/res",
|
||||||
"projects/some-gce-project/zones/us-central1-c/res",
|
"projects/some-gce-project/zones/us-central1-c/res",
|
||||||
"projects/some-gce-project/zones/us-central1-c/res/name/extra",
|
"projects/some-gce-project/zones/us-central1-c/res/name/extra",
|
||||||
} {
|
} {
|
||||||
@ -198,7 +260,28 @@ func TestSelfLink(t *testing.T) {
|
|||||||
"proj4",
|
"proj4",
|
||||||
"urlMaps",
|
"urlMaps",
|
||||||
meta.GlobalKey("key3"),
|
meta.GlobalKey("key3"),
|
||||||
"https://www.googleapis.com/compute/v1/projects/proj4/urlMaps/key3",
|
"https://www.googleapis.com/compute/v1/projects/proj4/global/urlMaps/key3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meta.VersionGA,
|
||||||
|
"proj4",
|
||||||
|
"projects",
|
||||||
|
nil,
|
||||||
|
"https://www.googleapis.com/compute/v1/projects/proj4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meta.VersionGA,
|
||||||
|
"proj4",
|
||||||
|
"regions",
|
||||||
|
meta.GlobalKey("us-central1"),
|
||||||
|
"https://www.googleapis.com/compute/v1/projects/proj4/regions/us-central1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meta.VersionGA,
|
||||||
|
"proj4",
|
||||||
|
"zones",
|
||||||
|
meta.GlobalKey("us-central1-a"),
|
||||||
|
"https://www.googleapis.com/compute/v1/projects/proj4/zones/us-central1-a",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
if link := SelfLink(tc.ver, tc.project, tc.resource, tc.key); link != tc.want {
|
if link := SelfLink(tc.ver, tc.project, tc.resource, tc.key); link != tc.want {
|
||||||
|
@ -321,7 +321,7 @@ func TestUpdateInternalLoadBalancerBackendServices(t *testing.T) {
|
|||||||
assert.Equal(
|
assert.Equal(
|
||||||
t,
|
t,
|
||||||
bs.HealthChecks,
|
bs.HealthChecks,
|
||||||
[]string{fmt.Sprintf("%s/healthChecks/k8s-%s-node", url_base, vals.ClusterID)},
|
[]string{fmt.Sprintf("%s/global/healthChecks/k8s-%s-node", url_base, vals.ClusterID)},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user