Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions pkg/manifests/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ type Factory struct {
type InfrastructureReader interface {
HighlyAvailableInfrastructure() bool
HostedControlPlane() bool
SingleNodeControlPlane() bool
TwoNodeControlPlane() bool
HighlyAvailableControlPlane() bool
}

// ProxyReader has methods to describe the proxy configuration.
Expand Down Expand Up @@ -2475,24 +2478,38 @@ func (f *Factory) ControlPlanePrometheusRule() (*monv1.PrometheusRule, error) {

r.Namespace = f.namespace

if f.infrastructure.HostedControlPlane() {
groups := []monv1.RuleGroup{}
for _, g := range r.Spec.Groups {
switch g.Name {
case "kubernetes-system-apiserver",
"kubernetes-system-controller-manager",
"kubernetes-system-scheduler":
// skip
default:
groups = append(groups, g)
}
}
r.Spec.Groups = groups
switch {
case f.infrastructure.HostedControlPlane():
r.Spec.Groups = filterRuleGroups(r, []string{
"kubernetes-system-apiserver",
"kubernetes-system-controller-manager",
"kubernetes-system-scheduler",
})
case !f.infrastructure.HighlyAvailableControlPlane():
r.Spec.Groups = filterRuleGroups(r, []string{
// This group supports the SNO cluster configuration currently, but not TNO ones (TNA and TNF). This is
// because upstream is only concerned with the broader HA and non-HA scenarios, and not any
// OpenShift-specific cluster configurations.
"kubernetes-resources",
})
}

return r, nil
}

func filterRuleGroups(rule *monv1.PrometheusRule, ignoreGroups []string) (groups []monv1.RuleGroup) {
for _, g := range rule.Spec.Groups {
if slices.ContainsFunc(ignoreGroups, func(ig string) bool {
return g.Name == ig
}) {
continue
}
groups = append(groups, g)
}

return
}

func (f *Factory) ControlPlaneKubeletServiceMonitors() ([]*monv1.ServiceMonitor, error) {
return serviceMonitors(f.config.CollectionProfilesFeatureGateEnabled, f.ControlPlaneKubeletServiceMonitor, f.ControlPlaneKubeletMinimalServiceMonitor)
}
Expand Down
21 changes: 20 additions & 1 deletion pkg/manifests/manifests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ import (
type fakeInfrastructureReader struct {
highlyAvailableInfrastructure bool
hostedControlPlane bool
singleNodeControlPlane bool
twoNodeControlPlane bool
}

func (f *fakeInfrastructureReader) HighlyAvailableControlPlane() bool {
return !f.singleNodeControlPlane && !f.twoNodeControlPlane
}

func (f *fakeInfrastructureReader) HighlyAvailableInfrastructure() bool {
Expand All @@ -50,8 +56,21 @@ func (f *fakeInfrastructureReader) HostedControlPlane() bool {
return f.hostedControlPlane
}

func (f *fakeInfrastructureReader) TwoNodeControlPlane() bool {
return f.twoNodeControlPlane
}

func (f *fakeInfrastructureReader) SingleNodeControlPlane() bool {
return f.singleNodeControlPlane
}

func defaultInfrastructureReader() InfrastructureReader {
return &fakeInfrastructureReader{highlyAvailableInfrastructure: true, hostedControlPlane: false}
return &fakeInfrastructureReader{
highlyAvailableInfrastructure: true,
hostedControlPlane: false,
singleNodeControlPlane: false,
twoNodeControlPlane: false,
}
}

type fakeProxyReader struct {
Expand Down
45 changes: 44 additions & 1 deletion pkg/operator/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ import (
type InfrastructureConfig struct {
highlyAvailableInfrastructure bool
hostedControlPlane bool
singleNodeControlPlane bool
twoNodeControlPlane bool
}

var (
Expand Down Expand Up @@ -96,20 +98,43 @@ func NewDefaultInfrastructureConfig() *InfrastructureConfig {
return &InfrastructureConfig{
highlyAvailableInfrastructure: true,
hostedControlPlane: false,
singleNodeControlPlane: false,
twoNodeControlPlane: false,
}
}

// NewInfrastructureConfig returns a new InfrastructureConfig from the given config.openshift.io/Infrastructure resource.
func NewInfrastructureConfig(i *configv1.Infrastructure) *InfrastructureConfig {
ic := NewDefaultInfrastructureConfig()

// Data plane topology modes
// SNO
if i.Status.InfrastructureTopology == configv1.SingleReplicaTopologyMode {
ic.highlyAvailableInfrastructure = false
}

// TNO includes DualReplica and TNF topology modes. The latter is not exposed in openshift/api/config/v1 yet.
// TNA has a third etcd node, and considered to be highly available.
if i.Status.InfrastructureTopology == configv1.DualReplicaTopologyMode {
ic.highlyAvailableInfrastructure = false
}

// Control plane topology modes
// SNO
if i.Status.ControlPlaneTopology == configv1.SingleReplicaTopologyMode {
ic.singleNodeControlPlane = true
}

// TNO includes DualReplica and TNF topology modes. The latter is not exposed in openshift/api/config/v1 yet.
// TNA has a third etcd node, and considered to be highly available.
if i.Status.ControlPlaneTopology == configv1.DualReplicaTopologyMode {
ic.twoNodeControlPlane = true
}

// External topology mode is used for hosted control planes.
if i.Status.ControlPlaneTopology == configv1.ExternalTopologyMode {
ic.hostedControlPlane = true
}

return ic
}

Expand All @@ -123,6 +148,24 @@ func (ic *InfrastructureConfig) HostedControlPlane() bool {
return ic.hostedControlPlane
}

// TwoNodeControlPlane implements the InfrastructureReader interface.
func (ic *InfrastructureConfig) TwoNodeControlPlane() bool {
return ic.twoNodeControlPlane
}

// SingleNodeControlPlane implements the InfrastructureReader interface.
func (ic *InfrastructureConfig) SingleNodeControlPlane() bool {
return ic.singleNodeControlPlane
}

// HighlyAvailableControlPlane implements the InfrastructureReader interface.
func (ic *InfrastructureConfig) HighlyAvailableControlPlane() bool {
// Following the same pattern as we do for HighlyAvailableInfrastructure, i.e.,
// assuming topologies other than the currently known non-HA ones to be HA.
// Additionally, a cluster may have a non-HA control plane and an HA infrastructure, and vice versa.
return !ic.singleNodeControlPlane && !ic.twoNodeControlPlane
}

// ProxyConfig stores information about the proxy configuration.
type ProxyConfig struct {
httpProxy string
Expand Down