• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubevirt / containerized-data-importer / #4794

14 Jul 2024 06:12PM UTC coverage: 58.983% (+0.01%) from 58.972%
#4794

push

travis-ci

web-flow
update to k8s 1.30 libs and controller-runtime 0.18.4 (#3336)

* make deps-update

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* ReourceRequirements -> VolumeResourceRequirements

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* fix calls to controller.Watch()

controller-runtime changed the API!

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* Fix errors with actual openshift/library-go lib

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* make all works now and everything compiles

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* fix "make update-codegen" because generate_groups.sh deprecated

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* run "make generate"

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

* fix transfer unittest because of change to controller-runtime

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

---------

Signed-off-by: Michael Henriksen <mhenriks@redhat.com>

6 of 238 new or added lines in 24 files covered. (2.52%)

10 existing lines in 4 files now uncovered.

16454 of 27896 relevant lines covered (58.98%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.49
/pkg/operator/controller/prometheus.go
1
/*
2
Copyright 2018 The CDI Authors.
3

4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    http://www.apache.org/licenses/LICENSE-2.0
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package controller
18

19
import (
20
        "context"
21
        "fmt"
22
        "os"
23
        "reflect"
24

25
        "github.com/go-logr/logr"
26
        promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
27

28
        rbacv1 "k8s.io/api/rbac/v1"
29
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
30
        "k8s.io/apimachinery/pkg/api/meta"
31
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32
        "k8s.io/apimachinery/pkg/runtime"
33

34
        "sigs.k8s.io/controller-runtime/pkg/client"
35
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
36
        "sigs.k8s.io/controller-runtime/pkg/source"
37

38
        "kubevirt.io/containerized-data-importer/pkg/common"
39
        cc "kubevirt.io/containerized-data-importer/pkg/controller/common"
40
        "kubevirt.io/containerized-data-importer/pkg/monitoring/rules"
41
        cdinamespaced "kubevirt.io/containerized-data-importer/pkg/operator/resources/namespaced"
42
        "kubevirt.io/containerized-data-importer/pkg/util"
43
        sdk "kubevirt.io/controller-lifecycle-operator-sdk/pkg/sdk"
44
)
45

46
const (
47
        ruleName                  = "prometheus-cdi-rules"
48
        rbacName                  = "cdi-monitoring"
49
        monitorName               = "service-monitor-cdi"
50
        defaultMonitoringNs       = "monitoring"
51
        defaultRunbookURLTemplate = "https://kubevirt.io/monitoring/runbooks/%s"
52
        runbookURLTemplateEnv     = "RUNBOOK_URL_TEMPLATE"
53
)
54

55
func ensurePrometheusResourcesExist(ctx context.Context, c client.Client, scheme *runtime.Scheme, owner metav1.Object) error {
1✔
56
        namespace := owner.GetNamespace()
1✔
57

1✔
58
        cr, err := cc.GetActiveCDI(ctx, c)
1✔
59
        if err != nil {
1✔
60
                return err
×
61
        }
×
62
        if cr == nil {
1✔
63
                return fmt.Errorf("no active CDI")
×
64
        }
×
65
        installerLabels := util.GetRecommendedInstallerLabelsFromCr(cr)
1✔
66

1✔
67
        prometheusResources := []client.Object{
1✔
68
                newPrometheusRule(namespace),
1✔
69
                newPrometheusServiceMonitor(namespace),
1✔
70
                newPrometheusRole(namespace),
1✔
71
                newPrometheusRoleBinding(namespace),
1✔
72
        }
1✔
73

1✔
74
        for _, desired := range prometheusResources {
2✔
75
                if err := sdk.SetLastAppliedConfiguration(desired, LastAppliedConfigAnnotation); err != nil {
1✔
76
                        return err
×
77
                }
×
78
                util.SetRecommendedLabels(desired, installerLabels, "cdi-operator")
1✔
79
                if err := controllerutil.SetControllerReference(owner, desired, scheme); err != nil {
1✔
80
                        return err
×
81
                }
×
82

83
                if err := c.Create(ctx, desired); err != nil {
2✔
84
                        if k8serrors.IsAlreadyExists(err) {
2✔
85
                                current := sdk.NewDefaultInstance(desired)
1✔
86
                                nn := client.ObjectKeyFromObject(desired)
1✔
87
                                if err := c.Get(ctx, nn, current); err != nil {
1✔
88
                                        return err
×
89
                                }
×
90
                                current, err = sdk.StripStatusFromObject(current)
1✔
91
                                if err != nil {
1✔
92
                                        return err
×
93
                                }
×
94
                                currentObjCopy := current.DeepCopyObject()
1✔
95
                                sdk.MergeLabelsAndAnnotations(desired, current)
1✔
96
                                merged, err := sdk.MergeObject(desired, current, LastAppliedConfigAnnotation)
1✔
97
                                if err != nil {
1✔
98
                                        return err
×
99
                                }
×
100
                                if !reflect.DeepEqual(currentObjCopy, merged) {
2✔
101
                                        if err := c.Update(ctx, merged); err != nil {
1✔
102
                                                return err
×
103
                                        }
×
104
                                }
105
                        } else {
×
106
                                return err
×
107
                        }
×
108
                }
109
        }
110

111
        return nil
1✔
112
}
113

114
func isPrometheusDeployed(logger logr.Logger, c client.Client, namespace string) (bool, error) {
1✔
115
        rule := &promv1.PrometheusRule{}
1✔
116
        key := client.ObjectKey{Namespace: namespace, Name: ruleName}
1✔
117
        if err := c.Get(context.TODO(), key, rule); err != nil {
2✔
118
                if meta.IsNoMatchError(err) {
1✔
119
                        logger.V(3).Info("No match error for PrometheusRule, must not have prometheus deployed")
×
120
                        return false, nil
×
121
                } else if !k8serrors.IsNotFound(err) {
1✔
122
                        return false, err
×
123
                }
×
124
        }
125

126
        return true, nil
1✔
127
}
128

129
func newPrometheusRule(namespace string) *promv1.PrometheusRule {
1✔
130
        promRule, err := rules.BuildPrometheusRule(namespace)
1✔
131
        if err != nil {
1✔
132
                panic(err)
×
133
        }
134

135
        return &promv1.PrometheusRule{
1✔
136
                ObjectMeta: promRule.ObjectMeta,
1✔
137
                Spec:       promRule.Spec,
1✔
138
        }
1✔
139
}
140

141
func newPrometheusRole(namespace string) *rbacv1.Role {
1✔
142
        return &rbacv1.Role{
1✔
143
                ObjectMeta: metav1.ObjectMeta{
1✔
144
                        Name:      rbacName,
1✔
145
                        Namespace: namespace,
1✔
146
                        Labels: map[string]string{
1✔
147
                                common.CDIComponentLabel:  "",
1✔
148
                                common.PrometheusLabelKey: common.PrometheusLabelValue,
1✔
149
                        },
1✔
150
                },
1✔
151
                Rules: cdinamespaced.GetPrometheusNamespacedRules(),
1✔
152
        }
1✔
153
}
1✔
154

155
func newPrometheusRoleBinding(namespace string) *rbacv1.RoleBinding {
1✔
156
        monitoringNamespace := getMonitoringNamespace()
1✔
157

1✔
158
        return &rbacv1.RoleBinding{
1✔
159
                ObjectMeta: metav1.ObjectMeta{
1✔
160
                        Name:      rbacName,
1✔
161
                        Namespace: namespace,
1✔
162
                        Labels: map[string]string{
1✔
163
                                common.CDIComponentLabel:  "",
1✔
164
                                common.PrometheusLabelKey: common.PrometheusLabelValue,
1✔
165
                        },
1✔
166
                },
1✔
167
                RoleRef: rbacv1.RoleRef{
1✔
168
                        APIGroup: "rbac.authorization.k8s.io",
1✔
169
                        Kind:     "Role",
1✔
170
                        Name:     rbacName,
1✔
171
                },
1✔
172
                Subjects: []rbacv1.Subject{
1✔
173
                        {
1✔
174
                                Kind:      "ServiceAccount",
1✔
175
                                Namespace: monitoringNamespace,
1✔
176
                                Name:      "prometheus-k8s",
1✔
177
                        },
1✔
178
                },
1✔
179
        }
1✔
180
}
1✔
181

182
func getMonitoringNamespace() string {
1✔
183
        if ns := os.Getenv("MONITORING_NAMESPACE"); ns != "" {
1✔
184
                return ns
×
185
        }
×
186

187
        return defaultMonitoringNs
1✔
188
}
189

190
func newPrometheusServiceMonitor(namespace string) *promv1.ServiceMonitor {
1✔
191
        return &promv1.ServiceMonitor{
1✔
192
                ObjectMeta: metav1.ObjectMeta{
1✔
193
                        Namespace: namespace,
1✔
194
                        Name:      monitorName,
1✔
195
                        Labels: map[string]string{
1✔
196
                                common.CDIComponentLabel:          "",
1✔
197
                                "openshift.io/cluster-monitoring": "",
1✔
198
                                common.PrometheusLabelKey:         common.PrometheusLabelValue,
1✔
199
                        },
1✔
200
                },
1✔
201
                Spec: promv1.ServiceMonitorSpec{
1✔
202
                        Selector: metav1.LabelSelector{
1✔
203
                                MatchLabels: map[string]string{
1✔
204
                                        common.PrometheusLabelKey: common.PrometheusLabelValue,
1✔
205
                                },
1✔
206
                        },
1✔
207
                        NamespaceSelector: promv1.NamespaceSelector{
1✔
208
                                MatchNames: []string{namespace},
1✔
209
                        },
1✔
210
                        Endpoints: []promv1.Endpoint{
1✔
211
                                {
1✔
212
                                        Port:   "metrics",
1✔
213
                                        Scheme: "http",
1✔
214
                                        TLSConfig: &promv1.TLSConfig{
1✔
215
                                                SafeTLSConfig: promv1.SafeTLSConfig{
1✔
216
                                                        InsecureSkipVerify: true,
1✔
217
                                                },
1✔
218
                                        },
1✔
219
                                },
1✔
220
                        },
1✔
221
                },
1✔
222
        }
1✔
223
}
1✔
224

225
func (r *ReconcileCDI) watchPrometheusResources() error {
×
226
        listObjs := []client.ObjectList{
×
227
                &promv1.PrometheusRuleList{},
×
228
                &promv1.ServiceMonitorList{},
×
229
        }
×
230

×
231
        objs := []client.Object{
×
232
                &promv1.PrometheusRule{},
×
233
                &promv1.ServiceMonitor{},
×
234
        }
×
235

×
236
        for i, listObj := range listObjs {
×
237
                obj := objs[i]
×
238
                err := r.uncachedClient.List(context.TODO(), listObj, &client.ListOptions{
×
239
                        Namespace: util.GetNamespace(),
×
240
                        Limit:     1,
×
241
                })
×
242
                if err == nil {
×
NEW
243
                        if err := r.controller.Watch(source.Kind(r.getCache(), obj, enqueueCDI(r.client))); err != nil {
×
244
                                return err
×
245
                        }
×
246
                } else if meta.IsNoMatchError(err) {
×
247
                        log.Info("Not watching", "type", fmt.Sprintf("%T", obj))
×
248
                } else {
×
249
                        return err
×
250
                }
×
251
        }
252

253
        objs = []client.Object{
×
254
                &rbacv1.Role{},
×
255
                &rbacv1.RoleBinding{},
×
256
        }
×
257

×
258
        for _, obj := range objs {
×
NEW
259
                if err := r.controller.Watch(source.Kind(r.getCache(), obj, enqueueCDI(r.client))); err != nil {
×
260
                        return err
×
261
                }
×
262
        }
263

264
        return nil
×
265
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc