From 34f9c73c791688ef989efe907f3dd0099439a331 Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Tue, 30 Apr 2024 15:21:15 +0100 Subject: [PATCH 1/7] Fix webhook panic when adding managed security groups Also adds fuzz tests which would have caught this and any similar issues. --- pkg/webhooks/fuzz_test.go | 92 ++++++++++++++++++++++++ pkg/webhooks/openstackcluster_webhook.go | 4 ++ 2 files changed, 96 insertions(+) create mode 100644 pkg/webhooks/fuzz_test.go diff --git a/pkg/webhooks/fuzz_test.go b/pkg/webhooks/fuzz_test.go new file mode 100644 index 0000000000..c4e246a78e --- /dev/null +++ b/pkg/webhooks/fuzz_test.go @@ -0,0 +1,92 @@ +/* +Copyright 2024 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 webhooks + +import ( + "context" + "runtime/debug" + "testing" + + "github.com/onsi/gomega/format" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" +) + +type pointerToObject[T any] interface { + *T + runtime.Object +} + +// fuzzCustomValidator fuzzes a CustomValidator with objects of the validator's expected type. +func fuzzCustomValidator[O any, PO pointerToObject[O]](t *testing.T, name string, validator webhook.CustomValidator) { + t.Helper() + fuzz := utilconversion.GetFuzzer(scheme.Scheme) + ctx := context.TODO() + + t.Run(name, func(t *testing.T) { + for i := 0; i < 1000; i++ { + var previous PO = new(O) + var dst PO = new(O) + fuzz.Fuzz(previous) + fuzz.Fuzz(dst) + + checkPanic := func(f func(), name string, args ...runtime.Object) { + defer func() { + if r := recover(); r != nil { + t.Errorf("PANIC in %s", name) + for i, arg := range args { + t.Errorf("arg %d:\n%s", i, format.Object(arg, 1)) + } + t.Errorf("Stack trace:\n%s", debug.Stack()) + t.FailNow() + } + }() + f() + } + + checkPanic(func() { + _, _ = validator.ValidateCreate(ctx, dst) + }, "ValidateCreate()", dst) + checkPanic(func() { + _, _ = validator.ValidateUpdate(ctx, previous, dst) + }, "ValidateUpdate()", previous, dst) + checkPanic(func() { + _, _ = validator.ValidateDelete(ctx, previous) + }, "ValidateDelete()", previous) + } + }) +} + +func Test_FuzzClusterWebhook(t *testing.T) { + fuzzCustomValidator[infrav1.OpenStackCluster](t, "OpenStackCluster", &openStackClusterWebhook{}) +} + +func Test_FuzzClusterTemplateWebhook(t *testing.T) { + fuzzCustomValidator[infrav1.OpenStackClusterTemplate](t, "OpenStackClusterTemplate", &openStackClusterTemplateWebhook{}) +} + +func Test_FuzzMachineWebhook(t *testing.T) { + fuzzCustomValidator[infrav1.OpenStackMachine](t, "OpenStackMachine", &openStackMachineWebhook{}) +} + +func Test_FuzzMachineTemplateWebhook(t *testing.T) { + fuzzCustomValidator[infrav1.OpenStackMachineTemplate](t, "OpenStackMachineTemplate", &openStackMachineTemplateWebhook{}) +} diff --git a/pkg/webhooks/openstackcluster_webhook.go b/pkg/webhooks/openstackcluster_webhook.go index 194933c3d6..910f761ebb 100644 --- a/pkg/webhooks/openstackcluster_webhook.go +++ b/pkg/webhooks/openstackcluster_webhook.go @@ -121,6 +121,10 @@ func (*openStackClusterWebhook) ValidateUpdate(_ context.Context, oldObjRaw, new // Allow changes to the managed allNodesSecurityGroupRules. if newObj.Spec.ManagedSecurityGroups != nil { + if oldObj.Spec.ManagedSecurityGroups == nil { + oldObj.Spec.ManagedSecurityGroups = &infrav1.ManagedSecurityGroups{} + } + oldObj.Spec.ManagedSecurityGroups.AllNodesSecurityGroupRules = []infrav1.SecurityGroupRuleSpec{} newObj.Spec.ManagedSecurityGroups.AllNodesSecurityGroupRules = []infrav1.SecurityGroupRuleSpec{} From 9082ab0f247293bcd6ebdd8975575bc84303e271 Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Fri, 3 May 2024 11:47:34 +0100 Subject: [PATCH 2/7] [release-0.10] Fix enabling of disabled bastion on upgrade to v1beta1 --- api/v1alpha5/zz_generated.conversion.go | 4 +-- api/v1alpha6/openstackcluster_conversion.go | 5 ++- api/v1alpha6/zz_generated.conversion.go | 4 +-- api/v1alpha7/openstackcluster_conversion.go | 5 ++- api/v1alpha7/zz_generated.conversion.go | 4 +-- api/v1beta1/types.go | 2 +- .../apivalidations/openstackcluster_test.go | 36 +++++++++++++++++++ 7 files changed, 51 insertions(+), 9 deletions(-) diff --git a/api/v1alpha5/zz_generated.conversion.go b/api/v1alpha5/zz_generated.conversion.go index a77967fb5a..fa585fef41 100644 --- a/api/v1alpha5/zz_generated.conversion.go +++ b/api/v1alpha5/zz_generated.conversion.go @@ -489,7 +489,7 @@ func Convert_v1beta1_AddressPair_To_v1alpha5_AddressPair(in *v1beta1.AddressPair } func autoConvert_v1alpha5_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.Bastion, s conversion.Scope) error { - if err := optional.Convert_bool_To_optional_Bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Instance requires manual conversion: does not exist in peer-type @@ -500,7 +500,7 @@ func autoConvert_v1alpha5_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.B } func autoConvert_v1beta1_Bastion_To_v1alpha5_Bastion(in *v1beta1.Bastion, out *Bastion, s conversion.Scope) error { - if err := optional.Convert_optional_Bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Spec requires manual conversion: does not exist in peer-type diff --git a/api/v1alpha6/openstackcluster_conversion.go b/api/v1alpha6/openstackcluster_conversion.go index 665977d7e1..3bbb3f97d8 100644 --- a/api/v1alpha6/openstackcluster_conversion.go +++ b/api/v1alpha6/openstackcluster_conversion.go @@ -478,7 +478,10 @@ func restorev1beta1Bastion(previous **infrav1.Bastion, dst **infrav1.Bastion) { optional.RestoreString(&(*previous).FloatingIP, &(*dst).FloatingIP) optional.RestoreString(&(*previous).AvailabilityZone, &(*dst).AvailabilityZone) - optional.RestoreBool(&(*previous).Enabled, &(*dst).Enabled) + + if (*dst).Enabled != nil && !*(*dst).Enabled { + (*dst).Enabled = (*previous).Enabled + } } func Convert_v1alpha6_Bastion_To_v1beta1_Bastion(in *Bastion, out *infrav1.Bastion, s apiconversion.Scope) error { diff --git a/api/v1alpha6/zz_generated.conversion.go b/api/v1alpha6/zz_generated.conversion.go index 59dba6198a..829e7d66a7 100644 --- a/api/v1alpha6/zz_generated.conversion.go +++ b/api/v1alpha6/zz_generated.conversion.go @@ -503,7 +503,7 @@ func Convert_v1beta1_AddressPair_To_v1alpha6_AddressPair(in *v1beta1.AddressPair } func autoConvert_v1alpha6_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.Bastion, s conversion.Scope) error { - if err := optional.Convert_bool_To_optional_Bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Instance requires manual conversion: does not exist in peer-type @@ -514,7 +514,7 @@ func autoConvert_v1alpha6_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.B } func autoConvert_v1beta1_Bastion_To_v1alpha6_Bastion(in *v1beta1.Bastion, out *Bastion, s conversion.Scope) error { - if err := optional.Convert_optional_Bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Spec requires manual conversion: does not exist in peer-type diff --git a/api/v1alpha7/openstackcluster_conversion.go b/api/v1alpha7/openstackcluster_conversion.go index 96e03b5c87..6b4a82a9bf 100644 --- a/api/v1alpha7/openstackcluster_conversion.go +++ b/api/v1alpha7/openstackcluster_conversion.go @@ -416,7 +416,10 @@ func restorev1beta1Bastion(previous **infrav1.Bastion, dst **infrav1.Bastion) { restorev1beta1MachineSpec((*previous).Spec, (*dst).Spec) optional.RestoreString(&(*previous).FloatingIP, &(*dst).FloatingIP) optional.RestoreString(&(*previous).AvailabilityZone, &(*dst).AvailabilityZone) - optional.RestoreBool(&(*previous).Enabled, &(*dst).Enabled) + + if (*dst).Enabled != nil && !*(*dst).Enabled { + (*dst).Enabled = (*previous).Enabled + } } func Convert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *infrav1.Bastion, s apiconversion.Scope) error { diff --git a/api/v1alpha7/zz_generated.conversion.go b/api/v1alpha7/zz_generated.conversion.go index f67c228983..a4144215b5 100644 --- a/api/v1alpha7/zz_generated.conversion.go +++ b/api/v1alpha7/zz_generated.conversion.go @@ -567,7 +567,7 @@ func Convert_v1beta1_AddressPair_To_v1alpha7_AddressPair(in *v1beta1.AddressPair } func autoConvert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.Bastion, s conversion.Scope) error { - if err := optional.Convert_bool_To_optional_Bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Instance requires manual conversion: does not exist in peer-type @@ -578,7 +578,7 @@ func autoConvert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.B } func autoConvert_v1beta1_Bastion_To_v1alpha7_Bastion(in *v1beta1.Bastion, out *Bastion, s conversion.Scope) error { - if err := optional.Convert_optional_Bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { return err } // WARNING: in.Spec requires manual conversion: does not exist in peer-type diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go index 7c13a3662d..5bbccb0504 100644 --- a/api/v1beta1/types.go +++ b/api/v1beta1/types.go @@ -795,7 +795,7 @@ type Bastion struct { // waiting until the bastion has been deleted. // +kubebuilder:default:=true // +optional - Enabled optional.Bool `json:"enabled,omitempty"` + Enabled *bool `json:"enabled,omitempty"` // Spec for the bastion itself Spec *OpenStackMachineSpec `json:"spec,omitempty"` diff --git a/test/e2e/suites/apivalidations/openstackcluster_test.go b/test/e2e/suites/apivalidations/openstackcluster_test.go index 9af5a730b1..80320e167c 100644 --- a/test/e2e/suites/apivalidations/openstackcluster_test.go +++ b/test/e2e/suites/apivalidations/openstackcluster_test.go @@ -215,6 +215,24 @@ var _ = Describe("OpenStackCluster API validations", func() { Expect(cluster.Spec.ControlPlaneEndpoint).To(Equal(*infrav1Cluster.Spec.ControlPlaneEndpoint), "Control plane endpoint should be restored") Expect(cluster.Spec.IdentityRef.Kind).To(Equal("FakeKind"), "IdentityRef.Kind should be restored") }) + + It("should not enable an explicitly disabled bastion when converting to v1beta1", func() { + cluster.Spec.Bastion = &infrav1alpha7.Bastion{Enabled: false} + Expect(create(cluster)).To(Succeed(), "OpenStackCluster creation should succeed") + + // Fetch the infrav1 version of the cluster + infrav1Cluster := &infrav1.OpenStackCluster{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, infrav1Cluster)).To(Succeed(), "OpenStackCluster fetch should succeed") + + infrav1Bastion := infrav1Cluster.Spec.Bastion + + // NOTE(mdbooth): It may be reasonable to remove the + // bastion if it is disabled with no other properties. + // It would be reasonable to update the assertions + // accordingly if we did that. + Expect(infrav1Bastion).ToNot(BeNil(), "Bastion should not have been removed") + Expect(infrav1Bastion.Enabled).To(Equal(ptr.To(false)), "Bastion should remain disabled") + }) }) Context("v1alpha6", func() { @@ -252,5 +270,23 @@ var _ = Describe("OpenStackCluster API validations", func() { Expect(cluster.Spec.ControlPlaneEndpoint).To(Equal(*infrav1Cluster.Spec.ControlPlaneEndpoint), "Control plane endpoint should be restored") Expect(cluster.Spec.IdentityRef.Kind).To(Equal("FakeKind"), "IdentityRef.Kind should be restored") }) + + It("should not enable an explicitly disabled bastion when converting to v1beta1", func() { + cluster.Spec.Bastion = &infrav1alpha6.Bastion{Enabled: false} + Expect(create(cluster)).To(Succeed(), "OpenStackCluster creation should succeed") + + // Fetch the infrav1 version of the cluster + infrav1Cluster := &infrav1.OpenStackCluster{} + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, infrav1Cluster)).To(Succeed(), "OpenStackCluster fetch should succeed") + + infrav1Bastion := infrav1Cluster.Spec.Bastion + + // NOTE(mdbooth): It may be reasonable to remove the + // bastion if it is disabled with no other properties. + // It would be reasonable to update the assertions + // accordingly if we did that. + Expect(infrav1Bastion).ToNot(BeNil(), "Bastion should not have been removed") + Expect(infrav1Bastion.Enabled).To(Equal(ptr.To(false)), "Bastion should remain disabled") + }) }) }) From d322e00e48f67835c7af66b780fa310572372b2a Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Fri, 3 May 2024 18:11:46 +0100 Subject: [PATCH 3/7] Fix empty version output in release builds --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a0991f0ed4..679fd36bc0 100644 --- a/Makefile +++ b/Makefile @@ -306,7 +306,7 @@ generate-api-docs-%: $(GEN_CRD_API_REFERENCE_DOCS) FORCE .PHONY: docker-build docker-build: ## Build the docker image for controller-manager - docker build -f Dockerfile --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg LDFLAGS="$(LDFLAGS)" . -t $(CONTROLLER_IMG_TAG) + docker build -f Dockerfile --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg ldflags="$(LDFLAGS)" . -t $(CONTROLLER_IMG_TAG) .PHONY: docker-push docker-push: ## Push the docker image From 5d578582a5d5b8a950322e08f1ddbea255c6dc09 Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Fri, 3 May 2024 18:41:01 +0100 Subject: [PATCH 4/7] Fix panic executing manager without valid kube context --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index c170553eeb..f39b683247 100644 --- a/main.go +++ b/main.go @@ -233,6 +233,7 @@ func main() { cfg, err := config.GetConfigWithContext(os.Getenv("KUBECONTEXT")) if err != nil { setupLog.Error(err, "unable to get kubeconfig") + os.Exit(1) } cfg.QPS = restConfigQPS cfg.Burst = restConfigBurst From 7731959b93e9648e132803584e5c47fa0c3d95cd Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Thu, 25 Apr 2024 15:14:29 +0200 Subject: [PATCH 5/7] Refactoring: never assign unacceptable TLS versions This commit makes security linting easier by never setting a TLS version outside v1.2 or v1.3, even in case of an unacceptable user input. --- main.go | 36 +++++++++++++--------------------- main_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/main.go b/main.go index c170553eeb..4cb02726bc 100644 --- a/main.go +++ b/main.go @@ -372,14 +372,19 @@ func concurrency(c int) controller.Options { func GetTLSOptionOverrideFuncs(options TLSOptions) ([]func(*tls.Config), error) { var tlsOptions []func(config *tls.Config) - tlsMinVersion, err := GetTLSVersion(options.TLSMinVersion) - if err != nil { - return nil, err - } - - tlsMaxVersion, err := GetTLSVersion(options.TLSMaxVersion) - if err != nil { - return nil, err + // To make a static analyzer happy, this block ensures there is no code + // path that sets a TLS version outside the acceptable values, even in + // case of unexpected user input. + var tlsMinVersion, tlsMaxVersion uint16 + for version, option := range map[*uint16]string{&tlsMinVersion: options.TLSMinVersion, &tlsMaxVersion: options.TLSMaxVersion} { + switch option { + case TLSVersion12: + *version = tls.VersionTLS12 + case TLSVersion13: + *version = tls.VersionTLS13 + default: + return nil, fmt.Errorf("unexpected TLS version %q (must be one of: %s)", option, strings.Join(tlsSupportedVersions, ", ")) + } } if tlsMaxVersion != 0 && tlsMinVersion > tlsMaxVersion { @@ -421,18 +426,3 @@ func GetTLSOptionOverrideFuncs(options TLSOptions) ([]func(*tls.Config), error) return tlsOptions, nil } - -// GetTLSVersion returns the corresponding tls.Version or error. -func GetTLSVersion(version string) (uint16, error) { - var v uint16 - - switch version { - case TLSVersion12: - v = tls.VersionTLS12 - case TLSVersion13: - v = tls.VersionTLS13 - default: - return 0, fmt.Errorf("unexpected TLS version %q (must be one of: %s)", version, strings.Join(tlsSupportedVersions, ", ")) - } - return v, nil -} diff --git a/main_test.go b/main_test.go index b4139280c8..fd1281f179 100644 --- a/main_test.go +++ b/main_test.go @@ -18,6 +18,7 @@ package main import ( "bytes" + "crypto/tls" "testing" . "github.com/onsi/gomega" @@ -75,25 +76,59 @@ func Test13CipherSuite(t *testing.T) { klog.SetOutput(bufWriter) klog.LogToStderr(false) // this is important, because klog by default logs to stderr only _, err := GetTLSOptionOverrideFuncs(tlsMockOptions) - g.Expect(bufWriter.String()).Should(ContainSubstring("warning: Cipher suites should not be set for TLS version 1.3. Ignoring ciphers")) g.Expect(err).Should(BeNil()) + g.Expect(bufWriter.String()).Should(ContainSubstring("warning: Cipher suites should not be set for TLS version 1.3. Ignoring ciphers")) }) } -func TestGetTLSVersion(t *testing.T) { - t.Run("should error out when incorrect tls version passed", func(t *testing.T) { +func TestGetTLSOverrideFuncs(t *testing.T) { + t.Run("should error out when incorrect min tls version passed", func(t *testing.T) { + g := NewWithT(t) + _, err := GetTLSOptionOverrideFuncs(TLSOptions{ + TLSMinVersion: "TLS11", + TLSMaxVersion: "TLS12", + }) + g.Expect(err.Error()).Should(Equal("unexpected TLS version \"TLS11\" (must be one of: TLS12, TLS13)")) + }) + t.Run("should error out when incorrect max tls version passed", func(t *testing.T) { g := NewWithT(t) - tlsVersion := "TLS11" - _, err := GetTLSVersion(tlsVersion) + _, err := GetTLSOptionOverrideFuncs(TLSOptions{ + TLSMinVersion: "TLS12", + TLSMaxVersion: "TLS11", + }) g.Expect(err.Error()).Should(Equal("unexpected TLS version \"TLS11\" (must be one of: TLS12, TLS13)")) }) - t.Run("should pass and output correct tls version", func(t *testing.T) { - const VersionTLS12 uint16 = 771 + t.Run("should apply the requested TLS versions", func(t *testing.T) { + g := NewWithT(t) + tlsOptionOverrides, err := GetTLSOptionOverrideFuncs(TLSOptions{ + TLSMinVersion: "TLS12", + TLSMaxVersion: "TLS13", + }) + + var tlsConfig tls.Config + for _, apply := range tlsOptionOverrides { + apply(&tlsConfig) + } + + g.Expect(err).Should(BeNil()) + g.Expect(tlsConfig.MinVersion).To(Equal(uint16(tls.VersionTLS12))) + g.Expect(tlsConfig.MaxVersion).To(Equal(uint16(tls.VersionTLS13))) + }) + t.Run("should apply the requested non-default TLS versions", func(t *testing.T) { g := NewWithT(t) - tlsVersion := "TLS12" - version, err := GetTLSVersion(tlsVersion) - g.Expect(version).To(Equal(VersionTLS12)) + tlsOptionOverrides, err := GetTLSOptionOverrideFuncs(TLSOptions{ + TLSMinVersion: "TLS13", + TLSMaxVersion: "TLS13", + }) + + var tlsConfig tls.Config + for _, apply := range tlsOptionOverrides { + apply(&tlsConfig) + } + g.Expect(err).Should(BeNil()) + g.Expect(tlsConfig.MinVersion).To(Equal(uint16(tls.VersionTLS13))) + g.Expect(tlsConfig.MaxVersion).To(Equal(uint16(tls.VersionTLS13))) }) } From a8285b1cafc5aa1badb60d595d75155f22d5bc6c Mon Sep 17 00:00:00 2001 From: Kashif Khan Date: Mon, 6 May 2024 17:51:33 +0300 Subject: [PATCH 6/7] Fix nil pointer issue while creating port Signed-off-by: Kashif Khan --- pkg/cloud/services/networking/port.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cloud/services/networking/port.go b/pkg/cloud/services/networking/port.go index 9d740ae3ff..0c86e7854b 100644 --- a/pkg/cloud/services/networking/port.go +++ b/pkg/cloud/services/networking/port.go @@ -192,7 +192,7 @@ func (s *Service) CreatePort(eventObject runtime.Object, portSpec *infrav1.Resol port, err := s.client.CreatePort(builder) if err != nil { - record.Warnf(eventObject, "FailedCreatePort", "Failed to create port %s: %v", port.Name, err) + record.Warnf(eventObject, "FailedCreatePort", "Failed to create port %s: %v", portSpec.Name, err) return nil, err } From 0ac498dd68e262ec7f4ac7736ae5c8e373e749da Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Wed, 8 May 2024 16:30:41 +0100 Subject: [PATCH 7/7] Set FallbackToLogsOnError on CAPO manager --- config/manager/manager.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 5ecf04a72d..6d54578783 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -46,6 +46,7 @@ spec: privileged: false runAsUser: 65532 runAsGroup: 65532 + terminationMessagePolicy: FallbackToLogsOnError terminationGracePeriodSeconds: 10 securityContext: runAsNonRoot: true