Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
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)
Comment thread
sthaha marked this conversation as 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