diff --git a/pkg/backends/syncer.go b/pkg/backends/syncer.go index dcfee12318..d1e9a73bc1 100644 --- a/pkg/backends/syncer.go +++ b/pkg/backends/syncer.go @@ -289,7 +289,11 @@ func (s *backendSyncer) ensureHealthCheck(sp utils.ServicePort) (string, error) return "", fmt.Errorf("Error getting prober: %w", err) } } - return s.healthChecker.SyncServicePort(&sp, probe) + i, err := s.cloud.ExtractClusterInfo() + if err != nil { + return "", fmt.Errorf("Error extracting cluster information: %w", err) + } + return s.healthChecker.SyncServicePort(&sp, probe, &i) } // getHealthCheckLink gets the Healthcheck link off the BackendService diff --git a/pkg/healthchecks/healthchecks.go b/pkg/healthchecks/healthchecks.go index cb7ae56451..f75df02e82 100644 --- a/pkg/healthchecks/healthchecks.go +++ b/pkg/healthchecks/healthchecks.go @@ -32,6 +32,7 @@ import ( "k8s.io/ingress-gce/pkg/loadbalancers/features" "k8s.io/ingress-gce/pkg/translator" "k8s.io/ingress-gce/pkg/utils" + "k8s.io/ingress-gce/pkg/utils/descutils" "k8s.io/klog/v2" ) @@ -53,7 +54,7 @@ func NewHealthChecker(cloud HealthCheckProvider, healthCheckPath string, default } // new returns a *HealthCheck with default settings and specified port/protocol -func (h *HealthChecks) new(sp utils.ServicePort) *translator.HealthCheck { +func (h *HealthChecks) new(sp utils.ServicePort, i descutils.ClusterInfo) *translator.HealthCheck { var hc *translator.HealthCheck if sp.NEGEnabled && !sp.L7ILBEnabled { hc = translator.DefaultNEGHealthCheck(sp.Protocol) @@ -67,12 +68,14 @@ func (h *HealthChecks) new(sp utils.ServicePort) *translator.HealthCheck { hc.Name = sp.BackendName() hc.Port = sp.NodePort hc.RequestPath = h.pathFromSvcPort(sp) + info := descutils.HealthcheckInfo{ClusterInfo: i, ServiceInfo: descutils.ServiceInfo(h.defaultBackendSvc), HealthcheckType: descutils.DefaultHC} // IngressType: ??? + hc.SetHealthcheckInfo(info) return hc } // SyncServicePort implements HealthChecker. -func (h *HealthChecks) SyncServicePort(sp *utils.ServicePort, probe *v1.Probe) (string, error) { - hc := h.new(*sp) +func (h *HealthChecks) SyncServicePort(sp *utils.ServicePort, probe *v1.Probe, i *descutils.ClusterInfo) (string, error) { + hc := h.new(*sp, *i) if probe != nil { klog.V(2).Infof("Applying httpGet settings of readinessProbe to health check on port %+v", sp) translator.ApplyProbeSettingsToHC(probe, hc) diff --git a/pkg/healthchecks/healthchecks_test.go b/pkg/healthchecks/healthchecks_test.go index f23e7637b1..d4f2d067e7 100644 --- a/pkg/healthchecks/healthchecks_test.go +++ b/pkg/healthchecks/healthchecks_test.go @@ -112,9 +112,10 @@ func init() { func TestHealthCheckAdd(t *testing.T) { fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) healthChecks := NewHealthChecker(fakeGCE, "/", defaultBackendSvc) + ci := gce.DefaultClusterInfo() sp := &utils.ServicePort{NodePort: 80, Protocol: annotations.ProtocolHTTP, NEGEnabled: false, BackendNamer: testNamer} - _, err := healthChecks.SyncServicePort(sp, nil) + _, err := healthChecks.SyncServicePort(sp, nil, &ci) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -125,7 +126,7 @@ func TestHealthCheckAdd(t *testing.T) { } sp = &utils.ServicePort{NodePort: 443, Protocol: annotations.ProtocolHTTPS, NEGEnabled: false, BackendNamer: testNamer} - _, err = healthChecks.SyncServicePort(sp, nil) + _, err = healthChecks.SyncServicePort(sp, nil, &ci) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -136,7 +137,7 @@ func TestHealthCheckAdd(t *testing.T) { } sp = &utils.ServicePort{NodePort: 3000, Protocol: annotations.ProtocolHTTP2, NEGEnabled: false, BackendNamer: testNamer} - _, err = healthChecks.SyncServicePort(sp, nil) + _, err = healthChecks.SyncServicePort(sp, nil, &ci) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -150,6 +151,7 @@ func TestHealthCheckAdd(t *testing.T) { func TestHealthCheckAddExisting(t *testing.T) { fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) healthChecks := NewHealthChecker(fakeGCE, "/", defaultBackendSvc) + ci := gce.DefaultClusterInfo() // HTTP // Manually insert a health check @@ -164,7 +166,7 @@ func TestHealthCheckAddExisting(t *testing.T) { sp := &utils.ServicePort{NodePort: 3000, Protocol: annotations.ProtocolHTTP, NEGEnabled: false, BackendNamer: testNamer} // Should not fail adding the same type of health check - _, err = healthChecks.SyncServicePort(sp, nil) + _, err = healthChecks.SyncServicePort(sp, nil, &ci) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -186,7 +188,7 @@ func TestHealthCheckAddExisting(t *testing.T) { fakeGCE.CreateHealthCheck(v1hc) sp = &utils.ServicePort{NodePort: 4000, Protocol: annotations.ProtocolHTTPS, NEGEnabled: false, BackendNamer: testNamer} - _, err = healthChecks.SyncServicePort(sp, nil) + _, err = healthChecks.SyncServicePort(sp, nil, &ci) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -208,7 +210,7 @@ func TestHealthCheckAddExisting(t *testing.T) { fakeGCE.CreateHealthCheck(v1hc) sp = &utils.ServicePort{NodePort: 5000, Protocol: annotations.ProtocolHTTPS, NEGEnabled: false, BackendNamer: testNamer} - _, err = healthChecks.SyncServicePort(sp, nil) + _, err = healthChecks.SyncServicePort(sp, nil, &ci) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -279,6 +281,7 @@ func TestHTTP2HealthCheckDelete(t *testing.T) { func TestRegionalHealthCheckDelete(t *testing.T) { fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) healthChecks := NewHealthChecker(fakeGCE, "/", defaultBackendSvc) + ci := gce.DefaultClusterInfo() hc := healthChecks.new( utils.ServicePort{ @@ -294,6 +297,7 @@ func TestRegionalHealthCheckDelete(t *testing.T) { L7ILBEnabled: true, BackendNamer: testNamer, }, + ci, ) hcName := testNamer.NEG("ns2", "svc2", 80) @@ -454,6 +458,7 @@ func TestRolloutUpdateCustomHCDescription(t *testing.T) { }() fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) + ci := gce.DefaultClusterInfo() var ( defaultSP *utils.ServicePort = testSPs["HTTP-80-reg-nil"] @@ -467,7 +472,7 @@ func TestRolloutUpdateCustomHCDescription(t *testing.T) { healthChecks := NewHealthChecker(fakeGCE, "/", defaultBackendSvc) - _, err := healthChecks.SyncServicePort(defaultSP, nil) + _, err := healthChecks.SyncServicePort(defaultSP, nil, &ci) if err != nil { t.Fatalf("unexpected err while syncing healthcheck, err %v", err) } @@ -479,7 +484,7 @@ func TestRolloutUpdateCustomHCDescription(t *testing.T) { outputDefaultHC.Description, translator.DescriptionForDefaultHealthChecks) } - _, err = healthChecks.SyncServicePort(backendConfigSP, nil) + _, err = healthChecks.SyncServicePort(backendConfigSP, nil, &ci) if err != nil { t.Fatalf("unexpected err while syncing healthcheck, err %v", err) } @@ -496,16 +501,23 @@ func TestRolloutUpdateCustomHCDescription(t *testing.T) { // Modify the flag and see what happens. flags.F.EnableUpdateCustomHealthCheckDescription = true - _, err = healthChecks.SyncServicePort(backendConfigSP, nil) + _, err = healthChecks.SyncServicePort(backendConfigSP, nil, &ci) if err != nil { t.Fatalf("unexpected err while syncing healthcheck, err %v", err) } outputBCHCWithFlag := getSingletonHealthcheck(t, fakeGCE) - if outputBCHCWithFlag.Description != translator.DescriptionForHealthChecksFromBackendConfig { + wantDescription := "" + + fmt.Sprintf("{\n") + + fmt.Sprintf(" \"K8sCluster\": \"/locations/%s/clusters/%s\",\n", gce.DefaultTestClusterValues().Region, gce.DefaultTestClusterValues().ClusterID) + + fmt.Sprintf(" \"K8sResource\": \"/namespaces/%s/services/%s\",\n", defaultBackendSvc.Namespace, defaultBackendSvc.Name) + + fmt.Sprintf(" \"Config\": \"BackendConfig\"\n") + + fmt.Sprintf("}") + + if outputBCHCWithFlag.Description != wantDescription { t.Fatalf("incorrect Description, is: \"%v\", want: \"%v\"", - outputBCHCWithFlag.Description, translator.DescriptionForHealthChecksFromBackendConfig) + outputBCHCWithFlag.Description, wantDescription) } // Verify that only the Description is modified after rollout. @@ -1325,15 +1337,27 @@ func TestSyncServicePort(t *testing.T) { // settings. for _, tc := range cases { + tc := *tc tc.updateHCDescription = true tc.desc = tc.desc + " with updateHCDescription" - cases = append(cases, tc) + copyOfWant := *tc.wantComputeHC + if tc.sp.BackendConfig != nil { + copyOfWant.Description = "" + + fmt.Sprintf("{\n") + + fmt.Sprintf(" \"K8sCluster\": \"/locations/%s/clusters/%s\",\n", gce.DefaultTestClusterValues().Region, gce.DefaultTestClusterValues().ClusterID) + + fmt.Sprintf(" \"K8sResource\": \"/namespaces/%s/services/%s\",\n", defaultBackendSvc.Namespace, defaultBackendSvc.Name) + + fmt.Sprintf(" \"Config\": \"BackendConfig\"\n") + + fmt.Sprintf("}") + } + tc.wantComputeHC = ©OfWant + cases = append(cases, &tc) } for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { flags.F.EnableUpdateCustomHealthCheckDescription = tc.updateHCDescription fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) + ci := gce.DefaultClusterInfo() mock := fakeGCE.Compute().(*cloud.MockGCE) setupMockUpdate(mock) @@ -1344,12 +1368,12 @@ func TestSyncServicePort(t *testing.T) { hcs := NewHealthChecker(fakeGCE, "/", defaultBackendSvc) - gotSelfLink, err := hcs.SyncServicePort(tc.sp, tc.probe) + gotSelfLink, err := hcs.SyncServicePort(tc.sp, tc.probe, &ci) if gotErr := err != nil; gotErr != tc.wantErr { - t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe) = _, %v; gotErr = %t, want %t\nsp = %s\nprobe = %s", err, gotErr, tc.wantErr, pretty.Sprint(tc.sp), pretty.Sprint(tc.probe)) + t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe, &ci) = _, %v; gotErr = %t, want %t\nsp = %s\nprobe = %s\nci = %s", err, gotErr, tc.wantErr, pretty.Sprint(tc.sp), pretty.Sprint(tc.probe), pretty.Sprint(ci)) } if tc.wantSelfLink != "" && gotSelfLink != tc.wantSelfLink { - t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe) = %q, _; want = %q", gotSelfLink, tc.wantSelfLink) + t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe, &ci) = %q, _; want = %q", gotSelfLink, tc.wantSelfLink) } verify := func() { @@ -1364,20 +1388,20 @@ func TestSyncServicePort(t *testing.T) { t.Fatalf("Got %d healthchecks, want 1\n%s", len(computeHCs), pretty.Sprint(computeHCs)) } - gotHC := computeHCs[0] // Filter out SelfLink because it is hard to deal with in the mock and // test cases. - filter := func(hc *compute.HealthCheck) { + filter := func(hc compute.HealthCheck) compute.HealthCheck { hc.SelfLink = "" if !tc.updateHCDescription { hc.Description = "" } + return hc } - filter(gotHC) - filter(tc.wantComputeHC) + gotHC := filter(*computeHCs[0]) + wantHC := filter(*tc.wantComputeHC) - if !reflect.DeepEqual(gotHC, tc.wantComputeHC) { - t.Fatalf("Compute healthcheck is:\n%s, want:\n%s", pretty.Sprint(gotHC), pretty.Sprint(tc.wantComputeHC)) + if !reflect.DeepEqual(gotHC, wantHC) { + t.Fatalf("Compute healthcheck is:\n%s, want:\n%s", pretty.Sprint(gotHC), pretty.Sprint(wantHC)) } } @@ -1390,12 +1414,12 @@ func TestSyncServicePort(t *testing.T) { return nil } - gotSelfLink, err = hcs.SyncServicePort(tc.sp, tc.probe) + gotSelfLink, err = hcs.SyncServicePort(tc.sp, tc.probe, &ci) if gotErr := err != nil; gotErr != tc.wantErr { - t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe) = %v; gotErr = %t, want %t\nsp = %s\nprobe = %s", err, gotErr, tc.wantErr, pretty.Sprint(tc.sp), pretty.Sprint(tc.probe)) + t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe, &ci) = %v; gotErr = %t, want %t\nsp = %s\nprobe = %s\nci = %s", err, gotErr, tc.wantErr, pretty.Sprint(tc.sp), pretty.Sprint(tc.probe), pretty.Sprint(ci)) } if tc.wantSelfLink != "" && gotSelfLink != tc.wantSelfLink { - t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe) = %q, _; want = %q", gotSelfLink, tc.wantSelfLink) + t.Errorf("hcs.SyncServicePort(tc.sp, tc.probe, &ci) = %q, _; want = %q", gotSelfLink, tc.wantSelfLink) } verify() }) diff --git a/pkg/healthchecks/interfaces.go b/pkg/healthchecks/interfaces.go index 60cb8d9f79..1957a9fd31 100644 --- a/pkg/healthchecks/interfaces.go +++ b/pkg/healthchecks/interfaces.go @@ -24,6 +24,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/ingress-gce/pkg/translator" "k8s.io/ingress-gce/pkg/utils" + "k8s.io/ingress-gce/pkg/utils/descutils" ) // HealthCheckProvider is an interface to manage a single GCE health check. @@ -52,7 +53,7 @@ type HealthChecker interface { // ServicePort and Pod Probe definition. // // `probe` can be nil if no probe exists. - SyncServicePort(sp *utils.ServicePort, probe *v1.Probe) (string, error) + SyncServicePort(sp *utils.ServicePort, probe *v1.Probe, i *descutils.ClusterInfo) (string, error) Delete(name string, scope meta.KeyType) error Get(name string, version meta.Version, scope meta.KeyType) (*translator.HealthCheck, error) } diff --git a/pkg/translator/healthchecks.go b/pkg/translator/healthchecks.go index caa541559c..8330a4f14c 100644 --- a/pkg/translator/healthchecks.go +++ b/pkg/translator/healthchecks.go @@ -32,6 +32,7 @@ import ( "k8s.io/ingress-gce/pkg/flags" "k8s.io/ingress-gce/pkg/loadbalancers/features" "k8s.io/ingress-gce/pkg/utils" + "k8s.io/ingress-gce/pkg/utils/descutils" "k8s.io/klog/v2" ) @@ -90,6 +91,19 @@ type HealthCheck struct { // compute struct back. computealpha.HTTPHealthCheck computealpha.HealthCheck + healthcheckInfo descutils.HealthcheckInfo +} + +func (hc *HealthCheck) UpdateHealthCheckType(t descutils.HealthcheckType) { + hc.healthcheckInfo.HealthcheckType = t + hc.SetHealthcheckInfo(hc.healthcheckInfo) // This is not a no-op. +} + +func (hc *HealthCheck) SetHealthcheckInfo(i descutils.HealthcheckInfo) { + hc.healthcheckInfo = i + if flags.F.EnableUpdateCustomHealthCheckDescription && i.HealthcheckType == descutils.BackendConfigHC { + hc.Description = descutils.GenerateHealthcheckDescriptionFromHealthcheckInfo(hc.healthcheckInfo) + } } // NewHealthCheck creates a HealthCheck which abstracts nested structs away @@ -227,6 +241,7 @@ func (hc *HealthCheck) UpdateFromBackendConfig(c *backendconfigv1.HealthCheckCon if flags.F.EnableUpdateCustomHealthCheckDescription { hc.Description = DescriptionForHealthChecksFromBackendConfig } + hc.UpdateHealthCheckType(descutils.BackendConfigHC) } // DefaultHealthCheck simply returns the default health check. @@ -337,4 +352,5 @@ func ApplyProbeSettingsToHC(p *v1.Probe, hc *HealthCheck) { } hc.Description = DescriptionForHealthChecksFromReadinessProbe + hc.UpdateHealthCheckType(descutils.ReadinessProbeHC) } diff --git a/pkg/utils/descutils/utils.go b/pkg/utils/descutils/utils.go index fdb371e726..b56a228c8f 100644 --- a/pkg/utils/descutils/utils.go +++ b/pkg/utils/descutils/utils.go @@ -16,7 +16,64 @@ limitations under the License. package descutils -import "fmt" +import ( + "encoding/json" + "fmt" + + "k8s.io/apimachinery/pkg/types" + "k8s.io/klog/v2" +) + +type ClusterInfo struct { + name string + location string + regional bool +} + +type ServiceInfo types.NamespacedName + +type HealthcheckType int + +const ( + DefaultHC HealthcheckType = 1 + ReadinessProbeHC HealthcheckType = 2 + BackendConfigHC HealthcheckType = 3 +) + +type HealthcheckInfo struct { + ClusterInfo + ServiceInfo + HealthcheckType + // IngressType string +} + +type HealthcheckDesc struct { + K8sCluster string + K8sResource string + // K8ResourceDependency string + Config string +} + +func NewClusterInfo(name, location string, regional bool) ClusterInfo { + return ClusterInfo{name, location, regional} +} + +func GenerateClusterDescriptionFromClusterInfo(i ClusterInfo) string { + // locType here differs from locType in GenerateClusterLink(). + locType := "zones" + if i.regional { + locType = "locations" + } + return fmt.Sprintf("/%s/%s/clusters/%s", locType, i.location, i.name) +} + +func NewServiceInfo(namespace, resourceName string) ServiceInfo { + return ServiceInfo{namespace, resourceName} +} + +func GenerateK8sResourceDescriptionFromServiceInfo(i ServiceInfo) string { + return GenerateK8sResourceLink(i.Namespace, "services", i.Name) +} func GenerateClusterLink(name, location string, regional bool) string { if name == "" || location == "" { @@ -33,3 +90,25 @@ func GenerateClusterLink(name, location string, regional bool) string { func GenerateK8sResourceLink(namespace, resourceType, resourceName string) string { return fmt.Sprintf("/namespaces/%s/%s/%s", namespace, resourceType, resourceName) } + +func GenerateHealthcheckDescriptionFromHealthcheckInfo(i HealthcheckInfo) string { + desc := HealthcheckDesc{} + desc.K8sCluster = GenerateClusterDescriptionFromClusterInfo(i.ClusterInfo) + desc.K8sResource = GenerateK8sResourceDescriptionFromServiceInfo(i.ServiceInfo) + // desc.K8ResourceDependency = i.IngressType + switch i.HealthcheckType { + case DefaultHC: + desc.Config = "Default" + case ReadinessProbeHC: + desc.Config = "ReadinessProbe" + case BackendConfigHC: + desc.Config = "BackendConfig" + default: + klog.Errorf("Unknown healthcheck type: %v.", i.HealthcheckType) + } + json, err := json.MarshalIndent(desc, "", " ") + if err != nil { + klog.Error("Failed to marshall HealthcheckDesc %s: %v", desc, err) + } + return string(json) +} diff --git a/pkg/utils/descutils/utils_test.go b/pkg/utils/descutils/utils_test.go index 8d29a7912d..882381c484 100644 --- a/pkg/utils/descutils/utils_test.go +++ b/pkg/utils/descutils/utils_test.go @@ -78,3 +78,58 @@ func TestK8sResourceLink(t *testing.T) { t.Errorf("unexpected cluster link: wanted %s, but got %s", expectedLink, generatedLink) } } + +func TestGenerateClusterDescriptionFromClusterInfo(t *testing.T) { + testName := "cluster-name" + testRegion := "pl-central7" + clusterInfo := NewClusterInfo(testName, testRegion, true) + expectedDescription := "/locations/pl-central7/clusters/cluster-name" + + generatedDescription := GenerateClusterDescriptionFromClusterInfo(clusterInfo) + if generatedDescription != expectedDescription { + t.Errorf("unexpected cluster description: wanted %s, but got %s", expectedDescription, generatedDescription) + } + + testZone := "pl-central7-g" + clusterInfo = NewClusterInfo(testName, testZone, false) + expectedDescription = "/zones/pl-central7-g/clusters/cluster-name" + + generatedDescription = GenerateClusterDescriptionFromClusterInfo(clusterInfo) + if generatedDescription != expectedDescription { + t.Errorf("unexpected cluster description: wanted %sv, but got %v", expectedDescription, generatedDescription) + } +} + +func TestGenerateK8sResourceDescriptionFromServiceInfo(t *testing.T) { + testName := "service-name" + testNamespace := "testNamespace" + serviceInfo := NewServiceInfo(testNamespace, testName) + expectedDescription := "/namespaces/testNamespace/services/service-name" + + generatedDescription := GenerateK8sResourceDescriptionFromServiceInfo(serviceInfo) + if generatedDescription != expectedDescription { + t.Errorf("unexpected service description: wanted %v, but got %v", expectedDescription, generatedDescription) + } +} + +func TestGenerateHealthcheckDescriptionFromHealthcheckInfo(t *testing.T) { + testCluster := "cluster-name" + testRegion := "pl-central7" + clusterInfo := NewClusterInfo(testCluster, testRegion, true) + testService := "service-name" + testNamespace := "testNamespace" + serviceInfo := NewServiceInfo(testNamespace, testService) + hcType := DefaultHC + i := HealthcheckInfo{ClusterInfo: clusterInfo, ServiceInfo: serviceInfo, HealthcheckType: hcType} + expectedDescription := "" + + "{\n" + + " \"K8sCluster\": \"/locations/pl-central7/clusters/cluster-name\",\n" + + " \"K8sResource\": \"/namespaces/testNamespace/services/service-name\",\n" + + " \"Config\": \"Default\"\n" + + "}" + + generatedDescription := GenerateHealthcheckDescriptionFromHealthcheckInfo(i) + if generatedDescription != expectedDescription { + t.Errorf("unexpected healthcheck description: wanted %v, but got %v", expectedDescription, generatedDescription) + } +} diff --git a/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce.go b/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce.go index 9ebadc19e2..a147865a86 100644 --- a/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce.go +++ b/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce.go @@ -43,7 +43,7 @@ import ( "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/informers" @@ -55,6 +55,7 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/client-go/util/flowcontrol" cloudprovider "k8s.io/cloud-provider" + "k8s.io/ingress-gce/pkg/utils/descutils" "k8s.io/klog/v2" ) @@ -726,6 +727,16 @@ func (g *Cloud) Region() string { return g.region } +// Regional returns true if the cluster is regional. +func (g *Cloud) Regional() bool { + return g.regional +} + +// Zone returns the zone. +func (g *Cloud) Zone() string { + return g.localZone +} + // OnXPN returns true if the cluster is running on a cross project network (XPN) func (g *Cloud) OnXPN() bool { return g.onXPN @@ -976,3 +987,20 @@ func (manager *gceServiceManager) getProjectsAPIEndpoint() string { return projectsAPIEndpoint } + +func (cloud *Cloud) ExtractClusterInfo() (descutils.ClusterInfo, error) { + var ans descutils.ClusterInfo + name, err := cloud.ClusterID.GetID() + if err != nil { + return ans, fmt.Errorf("Error getting cluster name: %w", err) + } + regional := cloud.Regional() + var location string + if regional { + location = cloud.Region() + } else { + location = cloud.Zone() + } + ans = descutils.NewClusterInfo(name, location, regional) + return ans, nil +} diff --git a/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce_fake.go b/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce_fake.go index d9aca0742f..6234f94a28 100644 --- a/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce_fake.go +++ b/vendor/k8s.io/cloud-provider-gcp/providers/gce/gce_fake.go @@ -26,6 +26,7 @@ import ( compute "google.golang.org/api/compute/v1" option "google.golang.org/api/option" "k8s.io/client-go/tools/cache" + "k8s.io/ingress-gce/pkg/utils/descutils" ) // TestClusterValues holds the config values for the fake/test gce cloud object. @@ -52,6 +53,13 @@ func DefaultTestClusterValues() TestClusterValues { } } +// DefaultClusterInfo creates descutils.ClusterInfo based on the output of +// DefaultTestClusterValues(). +func DefaultClusterInfo() descutils.ClusterInfo { + values := DefaultTestClusterValues() + return descutils.NewClusterInfo(values.ClusterID, values.Region, true) +} + // Stubs ClusterID so that ClusterID.getOrInitialize() does not require calling // gce.Initialize() func fakeClusterID(clusterID string) ClusterID {