Skip to content

Commit 2347d3f

Browse files
committed
Introduce insightsoperators.openshift.io CR & implement its gather status attribute
1 parent 11da6c7 commit 2347d3f

File tree

74 files changed

+7430
-16
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+7430
-16
lines changed

manifests/03-clusterrole.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ rules:
5959
- clusteroperators
6060
verbs:
6161
- create
62+
- apiGroups:
63+
- "operator.openshift.io"
64+
resources:
65+
- insightsoperators
66+
verbs:
67+
- get
68+
- update
69+
- patch
6270
- apiGroups:
6371
- "config.openshift.io"
6472
resources:
File renamed without changes.
File renamed without changes.

manifests/08-operator-crd.yaml

+257
Large diffs are not rendered by default.

manifests/09-operator-cr.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: operator.openshift.io/v1
2+
kind: InsightsOperator
3+
metadata:
4+
name: cluster
5+
annotations:
6+
include.release.openshift.io/ibm-cloud-managed: "true"
7+
include.release.openshift.io/self-managed-high-availability: "true"
8+
include.release.openshift.io/single-node-developer: "true"
9+
capability.openshift.io/name: Insights
10+
spec:
11+
logLevel: Normal
12+
managementState: Managed
13+
operatorLogLevel: Normal
File renamed without changes.
File renamed without changes.

pkg/controller/operator.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
10+
operatorv1client "github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1"
1011
"github.com/openshift/library-go/pkg/controller/controllercmd"
1112
"k8s.io/apimachinery/pkg/api/errors"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -63,6 +64,11 @@ func (s *Operator) Run(ctx context.Context, controller *controllercmd.Controller
6364
return err
6465
}
6566

67+
operatorClient, err := operatorv1client.NewForConfig(controller.KubeConfig)
68+
if err != nil {
69+
return err
70+
}
71+
6672
gatherProtoKubeConfig, gatherKubeConfig, metricsGatherKubeConfig, alertsGatherKubeConfig := prepareGatherConfigs(
6773
controller.ProtoKubeConfig, controller.KubeConfig, s.Impersonate,
6874
)
@@ -114,7 +120,7 @@ func (s *Operator) Run(ctx context.Context, controller *controllercmd.Controller
114120
gatherKubeConfig, gatherProtoKubeConfig, metricsGatherKubeConfig, alertsGatherKubeConfig, anonymizer,
115121
configObserver, insightsClient,
116122
)
117-
periodicGather := periodic.New(configObserver, rec, gatherers, anonymizer)
123+
periodicGather := periodic.New(configObserver, rec, gatherers, anonymizer, operatorClient.InsightsOperators())
118124
statusReporter.AddSources(periodicGather.Sources()...)
119125

120126
// check we can read IO container status and we are not in crash loop

pkg/controller/periodic/periodic.go

+105-13
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,45 @@ import (
44
"context"
55
"fmt"
66
"sort"
7+
"strings"
78
"time"
89

910
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1011
"k8s.io/apimachinery/pkg/util/wait"
1112
"k8s.io/klog/v2"
1213

14+
v1 "github.com/openshift/api/operator/v1"
15+
operatorv1client "github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1"
1316
"github.com/openshift/insights-operator/pkg/anonymization"
1417
"github.com/openshift/insights-operator/pkg/config/configobserver"
1518
"github.com/openshift/insights-operator/pkg/controllerstatus"
1619
"github.com/openshift/insights-operator/pkg/gather"
1720
"github.com/openshift/insights-operator/pkg/gatherers"
1821
"github.com/openshift/insights-operator/pkg/recorder"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
)
24+
25+
const (
26+
DataGatheredCondition = "DataGathered"
27+
// NoDataGathered is a reason when there is no data gathered - e.g the resource is not in a cluster
28+
NoDataGatheredReason = "NoData"
29+
// GatherError is a reason when there is some error and no data gathered
30+
GatherErrorReason = "Error"
31+
// GatheredOK is a reason when data is gathered as expected
32+
GatherOKReason = "GatheredOK"
33+
// GatherWithError is a reason when data is gathered partially or with another error message
34+
GatherWithErrorReason = "GatheredWithError"
1935
)
2036

2137
// Controller periodically runs gatherers, records their results to the recorder
2238
// and flushes the recorder to create archives
2339
type Controller struct {
24-
configurator configobserver.Configurator
25-
recorder recorder.FlushInterface
26-
gatherers []gatherers.Interface
27-
statuses map[string]controllerstatus.StatusController
28-
anonymizer *anonymization.Anonymizer
40+
configurator configobserver.Configurator
41+
recorder recorder.FlushInterface
42+
gatherers []gatherers.Interface
43+
statuses map[string]controllerstatus.StatusController
44+
anonymizer *anonymization.Anonymizer
45+
insightsOperatorCLI operatorv1client.InsightsOperatorInterface
2946
}
3047

3148
// New creates a new instance of Controller which periodically invokes the gatherers
@@ -35,6 +52,7 @@ func New(
3552
rec recorder.FlushInterface,
3653
listGatherers []gatherers.Interface,
3754
anonymizer *anonymization.Anonymizer,
55+
insightsOperatorCLI operatorv1client.InsightsOperatorInterface,
3856
) *Controller {
3957
statuses := make(map[string]controllerstatus.StatusController)
4058

@@ -44,11 +62,12 @@ func New(
4462
}
4563

4664
return &Controller{
47-
configurator: configurator,
48-
recorder: rec,
49-
gatherers: listGatherers,
50-
statuses: statuses,
51-
anonymizer: anonymizer,
65+
configurator: configurator,
66+
recorder: rec,
67+
gatherers: listGatherers,
68+
statuses: statuses,
69+
anonymizer: anonymizer,
70+
insightsOperatorCLI: insightsOperatorCLI,
5271
}
5372
}
5473

@@ -114,7 +133,7 @@ func (c *Controller) Gather() {
114133
}
115134

116135
allFunctionReports := make(map[string]gather.GathererFunctionReport)
117-
136+
gatherTime := metav1.Now()
118137
for _, gatherer := range gatherersToProcess {
119138
func() {
120139
name := gatherer.GetName()
@@ -142,8 +161,11 @@ func (c *Controller) Gather() {
142161
})
143162
}()
144163
}
145-
146-
err := gather.RecordArchiveMetadata(mapToArray(allFunctionReports), c.recorder, c.anonymizer)
164+
err := c.updateOperatorStatusCR(allFunctionReports, gatherTime)
165+
if err != nil {
166+
klog.Errorf("failed to update the Insights Operator CR status: %v", err)
167+
}
168+
err = gather.RecordArchiveMetadata(mapToArray(allFunctionReports), c.recorder, c.anonymizer)
147169
if err != nil {
148170
klog.Errorf("unable to record archive metadata because of error: %v", err)
149171
}
@@ -176,6 +198,76 @@ func (c *Controller) periodicTrigger(stopCh <-chan struct{}) {
176198
}
177199
}
178200

201+
func (c *Controller) updateOperatorStatusCR(allFunctionReports map[string]gather.GathererFunctionReport, gatherTime metav1.Time) error {
202+
insightsOperatorCR, err := c.insightsOperatorCLI.Get(context.Background(), "cluster", metav1.GetOptions{})
203+
if err != nil {
204+
return err
205+
}
206+
207+
ioCopy := insightsOperatorCR.DeepCopy()
208+
ioCopy.Status.GatherStatus.Gatherers = []v1.GathererStatus{}
209+
ioCopy.Status.GatherStatus.LastGatherTime = gatherTime
210+
ioCopy.Status.GatherStatus.LastGatherDuration = metav1.Duration{
211+
Duration: time.Since(gatherTime.Time),
212+
}
213+
214+
for k := range allFunctionReports {
215+
fr := allFunctionReports[k]
216+
// duration = 0 means the gatherer didn't run
217+
if fr.Duration == 0 {
218+
continue
219+
}
220+
221+
gs := createGathererStatus(&fr)
222+
ioCopy.Status.GatherStatus.Gatherers = append(ioCopy.Status.GatherStatus.Gatherers, gs)
223+
}
224+
225+
_, err = c.insightsOperatorCLI.UpdateStatus(context.Background(), ioCopy, metav1.UpdateOptions{})
226+
if err != nil {
227+
return err
228+
}
229+
return nil
230+
}
231+
232+
func createGathererStatus(gfr *gather.GathererFunctionReport) v1.GathererStatus {
233+
gs := v1.GathererStatus{
234+
Name: gfr.FuncName,
235+
LastGatherDuration: metav1.Duration{
236+
// v.Duration is in milliseconds and we need nanoseconds
237+
Duration: time.Duration(gfr.Duration * 1000000),
238+
},
239+
}
240+
con := metav1.Condition{
241+
Type: DataGatheredCondition,
242+
LastTransitionTime: metav1.Now(),
243+
}
244+
245+
if gfr.RecordsCount > 0 {
246+
con.Status = metav1.ConditionTrue
247+
con.Reason = GatherOKReason
248+
con.Message = fmt.Sprintf("Created %d records in the archive.", gfr.RecordsCount)
249+
250+
if len(gfr.Errors) > 0 {
251+
con.Reason = GatherWithErrorReason
252+
con.Message = fmt.Sprintf("%s Error is: %s", con.Message, strings.Join(gfr.Errors, ","))
253+
}
254+
255+
gs.Conditions = append(gs.Conditions, con)
256+
} else {
257+
con.Status = metav1.ConditionFalse
258+
con.Reason = NoDataGatheredReason
259+
260+
if len(gfr.Errors) > 0 {
261+
con.Reason = GatherErrorReason
262+
con.Message = strings.Join(gfr.Errors, ",")
263+
}
264+
265+
gs.Conditions = append(gs.Conditions, con)
266+
}
267+
268+
return gs
269+
}
270+
179271
func mapToArray(m map[string]gather.GathererFunctionReport) []gather.GathererFunctionReport {
180272
a := make([]gather.GathererFunctionReport, 0, len(m))
181273
for _, v := range m {

pkg/controller/periodic/periodic_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/stretchr/testify/assert"
1010

11+
fakeOperatorCli "github.com/openshift/client-go/operator/clientset/versioned/fake"
1112
"github.com/openshift/insights-operator/pkg/config"
1213
"github.com/openshift/insights-operator/pkg/gather"
1314
"github.com/openshift/insights-operator/pkg/gatherers"
@@ -172,6 +173,7 @@ func getMocksForPeriodicTest(listGatherers []gatherers.Interface, interval time.
172173
Gather: []string{gather.AllGatherersConst},
173174
}}
174175
mockRecorder := recorder.MockRecorder{}
175-
176-
return New(&mockConfigurator, &mockRecorder, listGatherers, nil), &mockRecorder
176+
fakeInsightsOperatorCli := fakeOperatorCli.NewSimpleClientset().OperatorV1().InsightsOperators()
177+
return New(&mockConfigurator, &mockRecorder, listGatherers, nil, fakeInsightsOperatorCli), &mockRecorder
177178
}
179+

vendor/github.com/openshift/client-go/operator/clientset/versioned/clientset.go

+118
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/openshift/client-go/operator/clientset/versioned/doc.go

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)