Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-14922: skip console-plugin installation if console CO is absent #2011

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion jsonnet/components/cluster-monitoring-operator.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function(params) {
{
apiGroups: ['config.openshift.io'],
resources: ['clusterversions'],
verbs: ['get'],
verbs: ['get', 'list', 'watch'],
},
{
apiGroups: ['config.openshift.io'],
Expand Down
2 changes: 2 additions & 0 deletions manifests/0000_50_cluster-monitoring-operator_02-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ rules:
- clusterversions
verbs:
- get
- list
- watch
- apiGroups:
- config.openshift.io
resources:
Expand Down
32 changes: 32 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,25 @@ func (c *Client) ConsoleListWatch(ctx context.Context) *cache.ListWatch {
}
}

func (c *Client) ClusterVersionListWatch(ctx context.Context, name string) *cache.ListWatch {
clusterVersionInterface := c.oscclient.ConfigV1().ClusterVersions()

return &cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return clusterVersionInterface.List(ctx,
metav1.ListOptions{
FieldSelector: fields.OneTermEqualSelector("metadata.name", name).String(),
})
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return clusterVersionInterface.Watch(ctx,
metav1.ListOptions{
FieldSelector: fields.OneTermEqualSelector("metadata.name", name).String(),
})
},
}
}

func (c *Client) ClusterOperatorListWatch(ctx context.Context, name string) *cache.ListWatch {
ClusterOperatorInterface := c.oscclient.ConfigV1().ClusterOperators()

Expand Down Expand Up @@ -1862,6 +1881,19 @@ func (c *Client) PodCapacity(ctx context.Context) (int, error) {
return int(podCapacityTotal), nil
}

func (c *Client) HasClusterCapability(ctx context.Context, capability configv1.ClusterVersionCapability) (bool, error) {
version, err := c.oscclient.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{})
if err != nil {
return false, err
}

return slices.Contains(version.Status.Capabilities.EnabledCapabilities, capability), nil
}

func (c *Client) HasConsoleCapability(ctx context.Context) (bool, error) {
return c.HasClusterCapability(ctx, configv1.ClusterVersionCapabilityConsole)
}

func (c *Client) CreateOrUpdateConsolePlugin(ctx context.Context, plg *consolev1.ConsolePlugin) error {
conClient := c.osconclient.ConsoleV1().ConsolePlugins()
existing, err := conClient.Get(ctx, plg.GetName(), metav1.GetOptions{})
Expand Down
62 changes: 36 additions & 26 deletions pkg/operator/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"k8s.io/component-base/metrics/legacyregistry"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
apiutilerrors "k8s.io/apimachinery/pkg/util/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/informers"
Expand Down Expand Up @@ -406,6 +407,20 @@ func New(
}
o.informers = append(o.informers, informer)

// Many of the cluster capabilities such as Console can be enabled after
// installation. So this watches for any updates to the ClusterVersion - version
informer = cache.NewSharedIndexInformer(
o.client.ClusterVersionListWatch(ctx, "version"),
&configv1.ClusterVersion{}, resyncPeriod, cache.Indexers{},
)
_, err = informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
UpdateFunc: func(_, newObj interface{}) { o.handleEvent(newObj) },
})
if err != nil {
return nil, err
}
o.informers = append(o.informers, informer)

// Setup PVC informers to sync annotation updates.
for _, ns := range []string{o.namespace, o.namespaceUserWorkload} {
informer = cache.NewSharedIndexInformer(
Expand Down Expand Up @@ -565,32 +580,27 @@ func (o *Operator) keyFunc(obj interface{}) (string, bool) {
func (o *Operator) handleEvent(obj interface{}) {
cmoConfigMap := o.namespace + "/" + o.configMapName

if _, ok := obj.(*configv1.Infrastructure); ok {
klog.Infof("Triggering update due to an infrastructure update")
o.enqueue(cmoConfigMap)
return
}

if _, ok := obj.(*configv1.APIServer); ok {
klog.Infof("Triggering update due to an apiserver config update")
o.enqueue(cmoConfigMap)
return
}

if _, ok := obj.(*v1.PersistentVolumeClaim); ok {
klog.Info("Triggering update due to a PVC update")
o.enqueue(cmoConfigMap)
return
}

if _, ok := obj.(*configv1.Console); ok {
klog.Info("Triggering update due to a console update")
o.enqueue(cmoConfigMap)
return
}

if _, ok := obj.(*configv1.ClusterOperator); ok {
klog.Info("Triggering update due to a cluster operator update")
switch obj.(type) {
case *v1.PersistentVolumeClaim,
*configv1.Infrastructure,
*configv1.APIServer,
*configv1.Console,
*configv1.ClusterOperator,
*configv1.ClusterVersion:
// Log GroupKind and Name of the obj
rtObj := obj.(k8sruntime.Object)
gk := rtObj.GetObjectKind().GroupVersionKind().GroupKind()
metaObj := obj.(metav1.Object)
name := metaObj.GetName()
if ns := metaObj.GetNamespace(); ns != "" {
name = ns + "/" + name
}
// NOTE: use %T to print the type if the gv information is absent
objKind := gk.String()
if objKind == "" {
objKind = fmt.Sprintf("%T", obj)
sthaha marked this conversation as resolved.
Show resolved Hide resolved
}
klog.Infof("Triggering an update due to a change in %s - %s", objKind, name)
o.enqueue(cmoConfigMap)
return
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/tasks/monitoring_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/openshift/cluster-monitoring-operator/pkg/client"
"github.com/openshift/cluster-monitoring-operator/pkg/manifests"
"github.com/pkg/errors"
"k8s.io/klog/v2"
)

type MonitoringPluginTask struct {
Expand All @@ -37,6 +38,22 @@ func NewMonitoringPluginTask(client *client.Client, factory *manifests.Factory,
}

func (t *MonitoringPluginTask) Run(ctx context.Context) error {
// NOTE: console capability (like other capabilities) can only go from
// disabled -> enabled and not the other way around, meaning that CMO
// doesn't have to deal with removal of the console plugin resources.
// Hence, skip installing console if console capability is disabled.
{
enabled, err := t.client.HasConsoleCapability(ctx)
if err != nil {
return errors.Wrap(err, "failed to determine if console capability is enabled")
}

if !enabled {
klog.V(4).Infof("Skipping installation of Console Plugin as console capability is disabled")
return nil
}
}

{ // plugin
plg, err := t.factory.MonitoringPlugin()
if err != nil {
Expand Down