From 4b9aa7c3c7470ad360b02a10b31cd744f11ae5dc Mon Sep 17 00:00:00 2001 From: Olivier Cazade Date: Mon, 23 Mar 2026 08:54:17 +0100 Subject: [PATCH 1/2] networking: Add networkObservability install config field Add support for controlling network observability installation via the networkObservability field in the install config. This field contains an installationPolicy that accepts "InstallAndEnable", "DoNotInstall", or empty string values, and defaults to "InstallAndEnable" when omitted. The field is propagated from the install config through to the cluster Network resource spec during manifest generation, allowing network observability to be installed by default with an opt-out mechanism. --- .../install.openshift.io_installconfigs.yaml | 19 ++++++++++ pkg/asset/agent/installconfig_test.go | 18 +++++++++ pkg/asset/installconfig/installconfig_test.go | 11 ++++++ pkg/asset/manifests/network.go | 27 +++++++++----- pkg/types/defaults/installconfig.go | 6 +++ pkg/types/defaults/installconfig_test.go | 37 +++++++++++++++++++ pkg/types/installconfig.go | 34 +++++++++++++++++ pkg/types/zz_generated.deepcopy.go | 26 +++++++++++++ 8 files changed, 169 insertions(+), 9 deletions(-) diff --git a/data/data/install.openshift.io_installconfigs.yaml b/data/data/install.openshift.io_installconfigs.yaml index 4cc5cc24036..660b263e0b8 100644 --- a/data/data/install.openshift.io_installconfigs.yaml +++ b/data/data/install.openshift.io_installconfigs.yaml @@ -4989,6 +4989,25 @@ spec: - cidr type: object type: array + networkObservability: + description: |- + NetworkObservability is an optional field that configures network observability installation + during cluster deployment (day-0). + When omitted, network observability will be installed unless this is a SNO cluster. + properties: + installationPolicy: + description: |- + InstallationPolicy controls whether network observability is installed during cluster deployment. + Valid values are "", "InstallAndEnable" and "DoNotInstall". + When set to "", network observability will be installed unless this is a SNO cluster. + When set to "InstallAndEnable", network observability will be installed and enabled. + When set to "DoNotInstall", network observability will not be installed. + enum: + - "" + - InstallAndEnable + - DoNotInstall + type: string + type: object networkType: default: OVNKubernetes description: |- diff --git a/pkg/asset/agent/installconfig_test.go b/pkg/asset/agent/installconfig_test.go index 85eb31cc2ce..d9ef7b4b32f 100644 --- a/pkg/asset/agent/installconfig_test.go +++ b/pkg/asset/agent/installconfig_test.go @@ -22,6 +22,13 @@ import ( "github.com/openshift/installer/pkg/types/vsphere" ) +var ( + defaultNetworkObservabilityInstallAndEnable = types.NetworkObservabilityInstallAndEnable + defaultNetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &defaultNetworkObservabilityInstallAndEnable, + } +) + func TestInstallConfigLoad(t *testing.T) { cases := []struct { name string @@ -471,6 +478,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1064,6 +1072,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1155,6 +1164,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1226,6 +1236,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1297,6 +1308,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1368,6 +1380,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1477,6 +1490,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1626,6 +1640,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1843,6 +1858,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -2165,6 +2181,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -2272,6 +2289,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", diff --git a/pkg/asset/installconfig/installconfig_test.go b/pkg/asset/installconfig/installconfig_test.go index 75f51fc8fd6..30cfce0bb92 100644 --- a/pkg/asset/installconfig/installconfig_test.go +++ b/pkg/asset/installconfig/installconfig_test.go @@ -19,6 +19,13 @@ import ( "github.com/openshift/installer/pkg/types/none" ) +var ( + defaultNetworkObservabilityInstallAndEnable = types.NetworkObservabilityInstallAndEnable + defaultNetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &defaultNetworkObservabilityInstallAndEnable, + } +) + func TestInstallConfigGenerate_FillsInDefaults(t *testing.T) { sshPublicKey := &sshPublicKey{} baseDomain := &baseDomain{"test-domain", types.ExternalPublishingStrategy} @@ -60,6 +67,7 @@ func TestInstallConfigGenerate_FillsInDefaults(t *testing.T) { HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -128,6 +136,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -229,6 +238,7 @@ wrong_key: wrong_value HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -285,6 +295,7 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}" HostPrefix: 23, }, }, + NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", diff --git a/pkg/asset/manifests/network.go b/pkg/asset/manifests/network.go index b79e7bb4896..8d6c0b232dd 100644 --- a/pkg/asset/manifests/network.go +++ b/pkg/asset/manifests/network.go @@ -70,6 +70,23 @@ func (no *Networking) Generate(_ context.Context, dependencies asset.Parents) er serviceNet = append(serviceNet, sn.String()) } + networkSpec := configv1.NetworkSpec{ + ClusterNetwork: clusterNet, + ServiceNetwork: serviceNet, + NetworkType: netConfig.NetworkType, + // Block all Service.ExternalIPs by default + ExternalIP: &configv1.ExternalIPConfig{ + Policy: &configv1.ExternalIPPolicy{}, + }, + } + + // Set networkObservability from the install config + if netConfig.NetworkObservability != nil && netConfig.NetworkObservability.InstallationPolicy != nil { + networkSpec.NetworkObservability = configv1.NetworkObservabilitySpec{ + InstallationPolicy: (*configv1.NetworkObservabilityInstallationPolicy)(netConfig.NetworkObservability.InstallationPolicy), + } + } + no.Config = &configv1.Network{ TypeMeta: metav1.TypeMeta{ APIVersion: configv1.SchemeGroupVersion.String(), @@ -79,15 +96,7 @@ func (no *Networking) Generate(_ context.Context, dependencies asset.Parents) er Name: "cluster", // not namespaced }, - Spec: configv1.NetworkSpec{ - ClusterNetwork: clusterNet, - ServiceNetwork: serviceNet, - NetworkType: netConfig.NetworkType, - // Block all Service.ExternalIPs by default - ExternalIP: &configv1.ExternalIPConfig{ - Policy: &configv1.ExternalIPPolicy{}, - }, - }, + Spec: networkSpec, } configData, err := yaml.Marshal(no.Config) diff --git a/pkg/types/defaults/installconfig.go b/pkg/types/defaults/installconfig.go index 1652b45b11b..32ec7da1038 100644 --- a/pkg/types/defaults/installconfig.go +++ b/pkg/types/defaults/installconfig.go @@ -59,6 +59,12 @@ func SetInstallConfigDefaults(c *types.InstallConfig) { }, } } + if c.Networking.NetworkObservability == nil { + installationPolicy := types.NetworkObservabilityInstallAndEnable + c.Networking.NetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &installationPolicy, + } + } if c.Publish == "" { c.Publish = types.ExternalPublishingStrategy diff --git a/pkg/types/defaults/installconfig_test.go b/pkg/types/defaults/installconfig_test.go index 2e1ecd517a6..c5c6903023b 100644 --- a/pkg/types/defaults/installconfig_test.go +++ b/pkg/types/defaults/installconfig_test.go @@ -21,6 +21,7 @@ import ( ) func defaultInstallConfig() *types.InstallConfig { + installationPolicy := types.NetworkObservabilityInstallAndEnable return &types.InstallConfig{ AdditionalTrustBundlePolicy: defaultAdditionalTrustBundlePolicy(), Networking: &types.Networking{ @@ -35,6 +36,9 @@ func defaultInstallConfig() *types.InstallConfig { HostPrefix: int32(defaultHostPrefix), }, }, + NetworkObservability: &types.NetworkObservability{ + InstallationPolicy: &installationPolicy, + }, }, ControlPlane: defaultMachinePool("master"), Compute: []types.MachinePool{*defaultMachinePool("worker")}, @@ -287,6 +291,39 @@ func TestSetInstallConfigDefaults(t *testing.T) { return c }(), }, + { + name: "NetworkObservability nil", + config: &types.InstallConfig{ + Networking: &types.Networking{ + NetworkObservability: nil, + }, + }, + expected: func() *types.InstallConfig { + c := defaultInstallConfig() + return c + }(), + }, + { + name: "NetworkObservability DoNotInstall", + config: &types.InstallConfig{ + Networking: &types.Networking{ + NetworkObservability: &types.NetworkObservability{ + InstallationPolicy: func() *types.NetworkObservabilityInstallationPolicy { + p := types.NetworkObservabilityDoNotInstall + return &p + }(), + }, + }, + }, + expected: func() *types.InstallConfig { + c := defaultInstallConfig() + doNotInstall := types.NetworkObservabilityDoNotInstall + c.Networking.NetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &doNotInstall, + } + return c + }(), + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/types/installconfig.go b/pkg/types/installconfig.go index c4fe6a7475d..293c194f17f 100644 --- a/pkg/types/installconfig.go +++ b/pkg/types/installconfig.go @@ -531,6 +531,13 @@ type Networking struct { // pod network when NetworkType is set to OVNKubernetes. OVNKubernetesConfig *OVNKubernetesConfig `json:"ovnKubernetesConfig,omitempty"` + // NetworkObservability is an optional field that configures network observability installation + // during cluster deployment (day-0). + // When omitted, network observability will be installed unless this is a SNO cluster. + // + // +optional + NetworkObservability *NetworkObservability `json:"networkObservability,omitempty"` + // Deprecated types, scheduled to be removed // Deprecated way to configure an IP address pool for machines. @@ -797,3 +804,30 @@ func OSImageStreamValues() []OSImageStream { OSImageStreamRHCOS10, } } + +// NetworkObservabilityInstallationPolicy is an enumeration of the available network observability installation policies +// Valid values are "", "InstallAndEnable", "DoNotInstall". +// +kubebuilder:validation:Enum="";InstallAndEnable;DoNotInstall +type NetworkObservabilityInstallationPolicy string + +const ( + // NetworkObservabilityNoOpinion means that the user has no opinion and the platform is left + // to choose reasonable defaults. The current default is to install and enable network observability. + // This is subject to change over time. + NetworkObservabilityNoOpinion NetworkObservabilityInstallationPolicy = "" + // NetworkObservabilityInstallAndEnable means that network observability should be installed and enabled during cluster deployment + NetworkObservabilityInstallAndEnable NetworkObservabilityInstallationPolicy = "InstallAndEnable" + // NetworkObservabilityDoNotInstall means that network observability should not be installed + NetworkObservabilityDoNotInstall NetworkObservabilityInstallationPolicy = "DoNotInstall" +) + +// NetworkObservability defines the configuration for network observability installation +type NetworkObservability struct { + // InstallationPolicy controls whether network observability is installed during cluster deployment. + // Valid values are "", "InstallAndEnable" and "DoNotInstall". + // When set to "", network observability will be installed unless this is a SNO cluster. + // When set to "InstallAndEnable", network observability will be installed and enabled. + // When set to "DoNotInstall", network observability will not be installed. + // +optional + InstallationPolicy *NetworkObservabilityInstallationPolicy `json:"installationPolicy,omitempty"` +} diff --git a/pkg/types/zz_generated.deepcopy.go b/pkg/types/zz_generated.deepcopy.go index 0cf5571f75a..22fa4b709df 100644 --- a/pkg/types/zz_generated.deepcopy.go +++ b/pkg/types/zz_generated.deepcopy.go @@ -690,6 +690,27 @@ func (in MirrorConfig) DeepCopy() MirrorConfig { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkObservability) DeepCopyInto(out *NetworkObservability) { + *out = *in + if in.InstallationPolicy != nil { + in, out := &in.InstallationPolicy, &out.InstallationPolicy + *out = new(NetworkObservabilityInstallationPolicy) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkObservability. +func (in *NetworkObservability) DeepCopy() *NetworkObservability { + if in == nil { + return nil + } + out := new(NetworkObservability) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Networking) DeepCopyInto(out *Networking) { *out = *in @@ -719,6 +740,11 @@ func (in *Networking) DeepCopyInto(out *Networking) { *out = new(OVNKubernetesConfig) (*in).DeepCopyInto(*out) } + if in.NetworkObservability != nil { + in, out := &in.NetworkObservability, &out.NetworkObservability + *out = new(NetworkObservability) + (*in).DeepCopyInto(*out) + } if in.DeprecatedMachineCIDR != nil { in, out := &in.DeprecatedMachineCIDR, &out.DeprecatedMachineCIDR *out = (*in).DeepCopy() From 05a6358756af37cd79298933d7e47f85aa4d6297 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Tue, 18 Aug 2026 15:02:28 -0700 Subject: [PATCH 2/2] Don't default Network config CR to InstallAndEnable. Update valid values. If there is no `networkObservability` settings in install-config.yaml, then it shouldn't set anything in the Network config CR instead of setting it to InstallAndEnable. This is important since these two states have slightly different meanings. InstallAndEnable will enable on SNO, whereas the default (no setting) will not. Valid values for `installationPolicy` are "InstallAndEnable" and "NoAction". --- .../install.openshift.io_installconfigs.yaml | 8 +-- pkg/asset/agent/installconfig_test.go | 18 ------ pkg/asset/installconfig/installconfig_test.go | 11 ---- pkg/asset/manifests/network.go | 2 +- pkg/types/defaults/installconfig.go | 7 --- pkg/types/defaults/installconfig_test.go | 37 ----------- pkg/types/installconfig.go | 21 +++---- pkg/types/validation/installconfig.go | 14 +++++ pkg/types/validation/installconfig_test.go | 63 +++++++++++++++++++ 9 files changed, 89 insertions(+), 92 deletions(-) diff --git a/data/data/install.openshift.io_installconfigs.yaml b/data/data/install.openshift.io_installconfigs.yaml index 660b263e0b8..52c7f3083e6 100644 --- a/data/data/install.openshift.io_installconfigs.yaml +++ b/data/data/install.openshift.io_installconfigs.yaml @@ -4998,14 +4998,12 @@ spec: installationPolicy: description: |- InstallationPolicy controls whether network observability is installed during cluster deployment. - Valid values are "", "InstallAndEnable" and "DoNotInstall". - When set to "", network observability will be installed unless this is a SNO cluster. + Valid values are "InstallAndEnable" and "NoAction". When set to "InstallAndEnable", network observability will be installed and enabled. - When set to "DoNotInstall", network observability will not be installed. + When set to "NoAction", nothing will be done regarding network observability. enum: - - "" - InstallAndEnable - - DoNotInstall + - NoAction type: string type: object networkType: diff --git a/pkg/asset/agent/installconfig_test.go b/pkg/asset/agent/installconfig_test.go index d9ef7b4b32f..85eb31cc2ce 100644 --- a/pkg/asset/agent/installconfig_test.go +++ b/pkg/asset/agent/installconfig_test.go @@ -22,13 +22,6 @@ import ( "github.com/openshift/installer/pkg/types/vsphere" ) -var ( - defaultNetworkObservabilityInstallAndEnable = types.NetworkObservabilityInstallAndEnable - defaultNetworkObservability = &types.NetworkObservability{ - InstallationPolicy: &defaultNetworkObservabilityInstallAndEnable, - } -) - func TestInstallConfigLoad(t *testing.T) { cases := []struct { name string @@ -478,7 +471,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1072,7 +1064,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1164,7 +1155,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1236,7 +1226,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1308,7 +1297,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1380,7 +1368,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1490,7 +1477,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1640,7 +1626,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -1858,7 +1843,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -2181,7 +2165,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -2289,7 +2272,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", diff --git a/pkg/asset/installconfig/installconfig_test.go b/pkg/asset/installconfig/installconfig_test.go index 30cfce0bb92..75f51fc8fd6 100644 --- a/pkg/asset/installconfig/installconfig_test.go +++ b/pkg/asset/installconfig/installconfig_test.go @@ -19,13 +19,6 @@ import ( "github.com/openshift/installer/pkg/types/none" ) -var ( - defaultNetworkObservabilityInstallAndEnable = types.NetworkObservabilityInstallAndEnable - defaultNetworkObservability = &types.NetworkObservability{ - InstallationPolicy: &defaultNetworkObservabilityInstallAndEnable, - } -) - func TestInstallConfigGenerate_FillsInDefaults(t *testing.T) { sshPublicKey := &sshPublicKey{} baseDomain := &baseDomain{"test-domain", types.ExternalPublishingStrategy} @@ -67,7 +60,6 @@ func TestInstallConfigGenerate_FillsInDefaults(t *testing.T) { HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -136,7 +128,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -238,7 +229,6 @@ wrong_key: wrong_value HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", @@ -295,7 +285,6 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}" HostPrefix: 23, }, }, - NetworkObservability: defaultNetworkObservability, }, ControlPlane: &types.MachinePool{ Name: "master", diff --git a/pkg/asset/manifests/network.go b/pkg/asset/manifests/network.go index 8d6c0b232dd..cfcc3afd1b7 100644 --- a/pkg/asset/manifests/network.go +++ b/pkg/asset/manifests/network.go @@ -83,7 +83,7 @@ func (no *Networking) Generate(_ context.Context, dependencies asset.Parents) er // Set networkObservability from the install config if netConfig.NetworkObservability != nil && netConfig.NetworkObservability.InstallationPolicy != nil { networkSpec.NetworkObservability = configv1.NetworkObservabilitySpec{ - InstallationPolicy: (*configv1.NetworkObservabilityInstallationPolicy)(netConfig.NetworkObservability.InstallationPolicy), + InstallationPolicy: configv1.NetworkObservabilityInstallationPolicy(*netConfig.NetworkObservability.InstallationPolicy), } } diff --git a/pkg/types/defaults/installconfig.go b/pkg/types/defaults/installconfig.go index 32ec7da1038..391809b5b8e 100644 --- a/pkg/types/defaults/installconfig.go +++ b/pkg/types/defaults/installconfig.go @@ -59,13 +59,6 @@ func SetInstallConfigDefaults(c *types.InstallConfig) { }, } } - if c.Networking.NetworkObservability == nil { - installationPolicy := types.NetworkObservabilityInstallAndEnable - c.Networking.NetworkObservability = &types.NetworkObservability{ - InstallationPolicy: &installationPolicy, - } - } - if c.Publish == "" { c.Publish = types.ExternalPublishingStrategy } diff --git a/pkg/types/defaults/installconfig_test.go b/pkg/types/defaults/installconfig_test.go index c5c6903023b..2e1ecd517a6 100644 --- a/pkg/types/defaults/installconfig_test.go +++ b/pkg/types/defaults/installconfig_test.go @@ -21,7 +21,6 @@ import ( ) func defaultInstallConfig() *types.InstallConfig { - installationPolicy := types.NetworkObservabilityInstallAndEnable return &types.InstallConfig{ AdditionalTrustBundlePolicy: defaultAdditionalTrustBundlePolicy(), Networking: &types.Networking{ @@ -36,9 +35,6 @@ func defaultInstallConfig() *types.InstallConfig { HostPrefix: int32(defaultHostPrefix), }, }, - NetworkObservability: &types.NetworkObservability{ - InstallationPolicy: &installationPolicy, - }, }, ControlPlane: defaultMachinePool("master"), Compute: []types.MachinePool{*defaultMachinePool("worker")}, @@ -291,39 +287,6 @@ func TestSetInstallConfigDefaults(t *testing.T) { return c }(), }, - { - name: "NetworkObservability nil", - config: &types.InstallConfig{ - Networking: &types.Networking{ - NetworkObservability: nil, - }, - }, - expected: func() *types.InstallConfig { - c := defaultInstallConfig() - return c - }(), - }, - { - name: "NetworkObservability DoNotInstall", - config: &types.InstallConfig{ - Networking: &types.Networking{ - NetworkObservability: &types.NetworkObservability{ - InstallationPolicy: func() *types.NetworkObservabilityInstallationPolicy { - p := types.NetworkObservabilityDoNotInstall - return &p - }(), - }, - }, - }, - expected: func() *types.InstallConfig { - c := defaultInstallConfig() - doNotInstall := types.NetworkObservabilityDoNotInstall - c.Networking.NetworkObservability = &types.NetworkObservability{ - InstallationPolicy: &doNotInstall, - } - return c - }(), - }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/types/installconfig.go b/pkg/types/installconfig.go index 293c194f17f..64feeeee08b 100644 --- a/pkg/types/installconfig.go +++ b/pkg/types/installconfig.go @@ -806,28 +806,23 @@ func OSImageStreamValues() []OSImageStream { } // NetworkObservabilityInstallationPolicy is an enumeration of the available network observability installation policies -// Valid values are "", "InstallAndEnable", "DoNotInstall". -// +kubebuilder:validation:Enum="";InstallAndEnable;DoNotInstall +// Valid values are "InstallAndEnable", "NoAction". +// +kubebuilder:validation:Enum=InstallAndEnable;NoAction type NetworkObservabilityInstallationPolicy string const ( - // NetworkObservabilityNoOpinion means that the user has no opinion and the platform is left - // to choose reasonable defaults. The current default is to install and enable network observability. - // This is subject to change over time. - NetworkObservabilityNoOpinion NetworkObservabilityInstallationPolicy = "" - // NetworkObservabilityInstallAndEnable means that network observability should be installed and enabled during cluster deployment + // NetworkObservabilityInstallAndEnable means that network observability should be installed and enabled during cluster deployment. NetworkObservabilityInstallAndEnable NetworkObservabilityInstallationPolicy = "InstallAndEnable" - // NetworkObservabilityDoNotInstall means that network observability should not be installed - NetworkObservabilityDoNotInstall NetworkObservabilityInstallationPolicy = "DoNotInstall" + // NetworkObservabilityNoAction means that nothing will be done regarding network observability. + NetworkObservabilityNoAction NetworkObservabilityInstallationPolicy = "NoAction" ) -// NetworkObservability defines the configuration for network observability installation +// NetworkObservability defines the configuration for network observability installation. type NetworkObservability struct { // InstallationPolicy controls whether network observability is installed during cluster deployment. - // Valid values are "", "InstallAndEnable" and "DoNotInstall". - // When set to "", network observability will be installed unless this is a SNO cluster. + // Valid values are "InstallAndEnable" and "NoAction". // When set to "InstallAndEnable", network observability will be installed and enabled. - // When set to "DoNotInstall", network observability will not be installed. + // When set to "NoAction", nothing will be done regarding network observability. // +optional InstallationPolicy *NetworkObservabilityInstallationPolicy `json:"installationPolicy,omitempty"` } diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index 2cb5689fd6d..220181f9e58 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -566,6 +566,20 @@ func validateNetworking(n *types.Networking, fldPath *field.Path) field.ErrorLis allErrs = append(allErrs, validateClusterNetwork(n, &cn, i, fldPath.Child("clusterNetwork").Index(i))...) } + if n.NetworkObservability != nil { + if n.NetworkObservability.InstallationPolicy == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("networkObservability", "installationPolicy"), "installationPolicy is required when networkObservability is specified")) + } else { + validPolicies := map[types.NetworkObservabilityInstallationPolicy]bool{ + types.NetworkObservabilityInstallAndEnable: true, + types.NetworkObservabilityNoAction: true, + } + if !validPolicies[*n.NetworkObservability.InstallationPolicy] { + allErrs = append(allErrs, field.NotSupported(fldPath.Child("networkObservability", "installationPolicy"), *n.NetworkObservability.InstallationPolicy, []string{string(types.NetworkObservabilityInstallAndEnable), string(types.NetworkObservabilityNoAction)})) + } + } + } + return allErrs } diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index 93b3d3ac94e..5732d1f4988 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -406,6 +406,69 @@ func TestValidateInstallConfig(t *testing.T) { }(), expectedError: `^networking\.networkType: Invalid value: "OpenShiftSDN": networkType OpenShiftSDN is not supported, please use OVNKubernetes$`, }, + { + name: "invalid networkObservability installationPolicy", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + invalidPolicy := types.NetworkObservabilityInstallationPolicy("test") + c.Networking.NetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &invalidPolicy, + } + return c + }(), + expectedError: `^networking\.networkObservability\.installationPolicy: Unsupported value: "test": supported values: "InstallAndEnable", "NoAction"$`, + }, + { + name: "missing networkObservability installationPolicy", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + c.Networking.NetworkObservability = &types.NetworkObservability{} + return c + }(), + expectedError: `^networking\.networkObservability\.installationPolicy: Required value: installationPolicy is required when networkObservability is specified$`, + }, + { + name: "blank networkObservability installationPolicy", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + blankPolicy := types.NetworkObservabilityInstallationPolicy("") + c.Networking.NetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &blankPolicy, + } + return c + }(), + expectedError: `^networking\.networkObservability\.installationPolicy: Unsupported value: "": supported values: "InstallAndEnable", "NoAction"$`, + }, + { + name: "valid networkObservability InstallAndEnable", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + policy := types.NetworkObservabilityInstallAndEnable + c.Networking.NetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &policy, + } + return c + }(), + }, + { + name: "valid networkObservability NoAction", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + policy := types.NetworkObservabilityNoAction + c.Networking.NetworkObservability = &types.NetworkObservability{ + InstallationPolicy: &policy, + } + return c + }(), + }, + { + name: "valid networkObservability absent", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + c.Networking.NetworkObservability = nil + return c + }(), + }, { name: "missing service network", installConfig: func() *types.InstallConfig {