diff --git a/pkg/openstack/events.go b/pkg/openstack/events.go new file mode 100644 index 0000000000..200b613d4a --- /dev/null +++ b/pkg/openstack/events.go @@ -0,0 +1,24 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package openstack + +const ( + eventLBForceInternal = "LoadBalancerForcedInternal" + eventLBExternalNetworkSearchFailed = "LoadBalancerExternalNetworkSearchFailed" + eventLBSourceRangesIgnored = "LoadBalancerSourceRangesIgnored" + eventLBAZIgnored = "LoadBalancerAvailabilityZonesIgnored" +) diff --git a/pkg/openstack/loadbalancer.go b/pkg/openstack/loadbalancer.go index 19f5d9e35f..fab2ad5008 100644 --- a/pkg/openstack/loadbalancer.go +++ b/pkg/openstack/loadbalancer.go @@ -1033,9 +1033,10 @@ func (lbaas *LbaasV2) ensureFloatingIP(clusterName string, service *corev1.Servi } klog.V(2).Infof("Successfully created floating IP %s for loadbalancer %s", floatIP.FloatingIP, lb.ID) } - } else { - klog.Warningf("Floating network configuration not provided for Service %s, forcing to ensure an internal load balancer service", serviceName) + msg := "Floating network configuration not provided for Service %s, forcing to ensure an internal load balancer service" + lbaas.eventRecorder.Eventf(service, corev1.EventTypeWarning, eventLBForceInternal, msg, serviceName) + klog.Warningf(msg, serviceName) } } @@ -1738,7 +1739,9 @@ func (lbaas *LbaasV2) checkService(service *corev1.Service, nodes []*corev1.Node if floatingNetworkID == "" { floatingNetworkID, err = openstackutil.GetFloatingNetworkID(lbaas.network) if err != nil { - klog.Warningf("Failed to find floating-network-id for Service %s: %v", serviceName, err) + msg := "Failed to find floating-network-id for Service %s: %v" + lbaas.eventRecorder.Eventf(service, corev1.EventTypeWarning, eventLBExternalNetworkSearchFailed, msg, serviceName, err) + klog.Warningf(msg, serviceName, err) } } @@ -1811,7 +1814,9 @@ func (lbaas *LbaasV2) checkService(service *corev1.Service, nodes []*corev1.Node klog.V(4).Info("LoadBalancerSourceRanges will be enforced on the SG created and attached to LB members") svcConf.allowedCIDR = sourceRanges.StringSlice() } else { - klog.Warning("LoadBalancerSourceRanges are ignored") + msg := "LoadBalancerSourceRanges are ignored for Service %s because Octavia provider does not support it" + lbaas.eventRecorder.Eventf(service, corev1.EventTypeWarning, eventLBSourceRangesIgnored, msg, serviceName) + klog.Warningf(msg, serviceName) } if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureFlavors, lbaas.opts.LBProvider) { @@ -1822,7 +1827,9 @@ func (lbaas *LbaasV2) checkService(service *corev1.Service, nodes []*corev1.Node if openstackutil.IsOctaviaFeatureSupported(lbaas.lb, openstackutil.OctaviaFeatureAvailabilityZones, lbaas.opts.LBProvider) { svcConf.availabilityZone = availabilityZone } else if availabilityZone != "" { - klog.Warning("LoadBalancer Availability Zones aren't supported. Please, upgrade Octavia API to version 2.14 or later (Ussuri release) to use them") + msg := "LoadBalancer Availability Zones aren't supported. Please, upgrade Octavia API to version 2.14 or later (Ussuri release) to use them for Service %s" + lbaas.eventRecorder.Eventf(service, corev1.EventTypeWarning, eventLBAZIgnored, msg, serviceName) + klog.Warningf(msg, serviceName) } svcConf.enableMonitor = getBoolFromServiceAnnotation(service, ServiceAnnotationLoadBalancerEnableHealthMonitor, lbaas.opts.CreateMonitor) diff --git a/pkg/openstack/openstack.go b/pkg/openstack/openstack.go index ab0baf5ce1..c0c8bcd16a 100644 --- a/pkg/openstack/openstack.go +++ b/pkg/openstack/openstack.go @@ -36,8 +36,12 @@ import ( cloudprovider "k8s.io/cloud-provider" "k8s.io/klog/v2" + "k8s.io/api/core/v1" "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers/core/v1" + "k8s.io/client-go/kubernetes/scheme" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/tools/record" "k8s.io/cloud-provider-openstack/pkg/client" "k8s.io/cloud-provider-openstack/pkg/metrics" "k8s.io/cloud-provider-openstack/pkg/util" @@ -76,11 +80,12 @@ type PortWithTrunkDetails struct { // LoadBalancer is used for creating and maintaining load balancers type LoadBalancer struct { - secret *gophercloud.ServiceClient - network *gophercloud.ServiceClient - lb *gophercloud.ServiceClient - opts LoadBalancerOpts - kclient kubernetes.Interface + secret *gophercloud.ServiceClient + network *gophercloud.ServiceClient + lb *gophercloud.ServiceClient + opts LoadBalancerOpts + kclient kubernetes.Interface + eventRecorder record.EventRecorder } // LoadBalancerOpts have the options to talk to Neutron LBaaSV2 or Octavia @@ -160,6 +165,9 @@ type OpenStack struct { useV1Instances bool // TODO: v1 instance apis can be deleted after the v2 is verified enough nodeInformer coreinformers.NodeInformer nodeInformerHasSynced func() bool + + eventBroadcaster record.EventBroadcaster + eventRecorder record.EventRecorder } // Config is used to read and store information from the cloud configuration file @@ -193,6 +201,9 @@ func init() { func (os *OpenStack) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) { clientset := clientBuilder.ClientOrDie("cloud-controller-manager") os.kclient = clientset + os.eventBroadcaster = record.NewBroadcaster() + os.eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: os.kclient.CoreV1().Events("")}) + os.eventRecorder = os.eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-provider-openstack"}) } // ReadConfig reads values from the cloud.conf @@ -367,7 +378,7 @@ func (os *OpenStack) LoadBalancer() (cloudprovider.LoadBalancer, bool) { klog.V(1).Info("Claiming to support LoadBalancer") - return &LbaasV2{LoadBalancer{secret, network, lb, os.lbOpts, os.kclient}}, true + return &LbaasV2{LoadBalancer{secret, network, lb, os.lbOpts, os.kclient, os.eventRecorder}}, true } // Zones indicates that we support zones