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

kubevirt / hyperconverged-cluster-operator / 11575589529

29 Oct 2024 02:03PM UTC coverage: 72.47% (-0.02%) from 72.494%
11575589529

Pull #3153

github

machadovilaca
Upgrade operator-observability package and remove deprecated functions

Signed-off-by: João Vilaça <machadovilaca@gmail.com>
Pull Request #3153: Upgrade operator-observability package and remove deprecated functions

8 of 9 new or added lines in 3 files covered. (88.89%)

3 existing lines in 1 file now uncovered.

6044 of 8340 relevant lines covered (72.47%)

0.8 hits per line

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

86.14
/controllers/operands/operandHandler.go
1
package operands
2

3
import (
4
        "context"
5
        "fmt"
6
        "time"
7

8
        log "github.com/go-logr/logr"
9
        "golang.org/x/sync/errgroup"
10
        corev1 "k8s.io/api/core/v1"
11
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
        "k8s.io/apimachinery/pkg/runtime"
13
        "sigs.k8s.io/controller-runtime/pkg/client"
14
        logf "sigs.k8s.io/controller-runtime/pkg/log"
15

16
        kubevirtcorev1 "kubevirt.io/api/core/v1"
17
        cdiv1beta1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
18

19
        hcov1beta1 "github.com/kubevirt/hyperconverged-cluster-operator/api/v1beta1"
20
        "github.com/kubevirt/hyperconverged-cluster-operator/controllers/common"
21
        "github.com/kubevirt/hyperconverged-cluster-operator/pkg/monitoring/metrics"
22
        hcoutil "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
23
)
24

25
const (
26
        reconcileFailed       = "ReconcileFailed"
27
        ErrCDIUninstall       = "ErrCDIUninstall"
28
        uninstallCDIErrorMsg  = "The uninstall request failed on CDI component: "
29
        ErrVirtUninstall      = "ErrVirtUninstall"
30
        uninstallVirtErrorMsg = "The uninstall request failed on virt component: "
31
        ErrHCOUninstall       = "ErrHCOUninstall"
32
        uninstallHCOErrorMsg  = "The uninstall request failed on dependent components, please check their logs."
33
        deleteTimeOut         = 30 * time.Second
34
)
35

36
// common constants
37
const (
38
        kvPriorityClass = "kubevirt-cluster-critical"
39
)
40

41
var (
42
        logger = logf.Log.WithName("operandHandlerInit")
43
)
44

45
type OperandHandler struct {
46
        client   client.Client
47
        operands []Operand
48
        // save for deletions
49
        objects      []client.Object
50
        eventEmitter hcoutil.EventEmitter
51
}
52

53
func NewOperandHandler(client client.Client, scheme *runtime.Scheme, ci hcoutil.ClusterInfo, eventEmitter hcoutil.EventEmitter) *OperandHandler {
1✔
54
        operands := []Operand{
1✔
55
                (*genericOperand)(newKvPriorityClassHandler(client, scheme)),
1✔
56
                (*genericOperand)(newKubevirtHandler(client, scheme)),
1✔
57
                (*genericOperand)(newCdiHandler(client, scheme)),
1✔
58
                (*genericOperand)(newCnaHandler(client, scheme)),
1✔
59
                newAAQHandler(client, scheme),
1✔
60
        }
1✔
61

1✔
62
        if ci.IsOpenshift() {
2✔
63
                operands = append(operands, []Operand{
1✔
64
                        (*genericOperand)(newSspHandler(client, scheme)),
1✔
65
                        (*genericOperand)(newCliDownloadHandler(client, scheme)),
1✔
66
                        (*genericOperand)(newCliDownloadsRouteHandler(client, scheme)),
1✔
67
                        (*genericOperand)(newServiceHandler(client, scheme, NewCliDownloadsService)),
1✔
68
                }...)
1✔
69
        }
1✔
70

71
        if ci.IsOpenshift() && ci.IsConsolePluginImageProvided() {
2✔
72
                operands = append(operands, newConsoleHandler(client))
1✔
73
                operands = append(operands, (*genericOperand)(newServiceHandler(client, scheme, NewKvUIPluginSvc)))
1✔
74
                operands = append(operands, (*genericOperand)(newServiceHandler(client, scheme, NewKvUIProxySvc)))
1✔
75
        }
1✔
76

77
        if ci.IsManagedByOLM() {
2✔
78
                operands = append(operands, newCsvHandler(client, ci))
1✔
79
        }
1✔
80

81
        return &OperandHandler{
1✔
82
                client:       client,
1✔
83
                operands:     operands,
1✔
84
                eventEmitter: eventEmitter,
1✔
85
        }
1✔
86
}
87

88
// FirstUseInitiation is a lazy init function
89
// The k8s client is not available when calling to NewOperandHandler.
90
// Initial operations that need to read/write from the cluster can only be done when the client is already working.
91
func (h *OperandHandler) FirstUseInitiation(scheme *runtime.Scheme, ci hcoutil.ClusterInfo, hc *hcov1beta1.HyperConverged) {
1✔
92
        h.objects = make([]client.Object, 0)
1✔
93
        if ci.IsOpenshift() {
2✔
94
                h.addOperands(scheme, hc, getQuickStartHandlers)
1✔
95
                h.addOperands(scheme, hc, getDashboardHandlers)
1✔
96
                h.addOperands(scheme, hc, getImageStreamHandlers)
1✔
97
                h.addOperand(scheme, hc, newVirtioWinCmHandler)
1✔
98
                h.addOperand(scheme, hc, newVirtioWinCmReaderRoleHandler)
1✔
99
                h.addOperand(scheme, hc, newVirtioWinCmReaderRoleBindingHandler)
1✔
100
        }
1✔
101

102
        if ci.IsOpenshift() && ci.IsConsolePluginImageProvided() {
2✔
103
                h.addOperand(scheme, hc, newKvUIPluginDeploymentHandler)
1✔
104
                h.addOperand(scheme, hc, newKvUIProxyDeploymentHandler)
1✔
105
                h.addOperand(scheme, hc, newKvUINginxCMHandler)
1✔
106
                h.addOperand(scheme, hc, newKvUIPluginCRHandler)
1✔
107
                h.addOperand(scheme, hc, newKvUIUserSettingsCMHandler)
1✔
108
                h.addOperand(scheme, hc, newKvUIFeaturesCMHandler)
1✔
109
                h.addOperand(scheme, hc, newKvUIConfigReaderRoleHandler)
1✔
110
                h.addOperand(scheme, hc, newKvUIConfigReaderRoleBindingHandler)
1✔
111

1✔
112
        }
1✔
113
}
114

115
func (h *OperandHandler) GetQuickStartNames() []string {
×
116
        return quickstartNames
×
117
}
×
118

119
type GetHandlers func(log.Logger, client.Client, *runtime.Scheme, *hcov1beta1.HyperConverged) ([]Operand, error)
120

121
func (h *OperandHandler) addOperandObject(handler Operand, hc *hcov1beta1.HyperConverged) {
1✔
122
        var (
1✔
123
                obj client.Object
1✔
124
                err error
1✔
125
        )
1✔
126

1✔
127
        if gh, ok := handler.(crGetter); ok {
2✔
128
                obj, err = gh.getFullCr(hc)
1✔
129
        } else {
1✔
130
                err = fmt.Errorf("unknown handler with type %T", handler)
×
131
        }
×
132

133
        if err != nil {
1✔
134
                logger.Error(err, "can't create object")
×
135
        } else {
1✔
136
                h.objects = append(h.objects, obj)
1✔
137
        }
1✔
138
}
139

140
func (h *OperandHandler) addOperands(scheme *runtime.Scheme, hc *hcov1beta1.HyperConverged, getHandlers GetHandlers) {
1✔
141
        handlers, err := getHandlers(logger, h.client, scheme, hc)
1✔
142
        if err != nil {
1✔
143
                logger.Error(err, "can't create handler")
×
144
        } else if len(handlers) > 0 {
2✔
145
                for _, handler := range handlers {
2✔
146
                        h.addOperandObject(handler, hc)
1✔
147
                }
1✔
148
                h.operands = append(h.operands, handlers...)
1✔
149
        }
150
}
151

152
type GetHandler func(log.Logger, client.Client, *runtime.Scheme, *hcov1beta1.HyperConverged) (Operand, error)
153

154
func (h *OperandHandler) addOperand(scheme *runtime.Scheme, hc *hcov1beta1.HyperConverged, getHandler GetHandler) {
1✔
155
        handler, err := getHandler(logger, h.client, scheme, hc)
1✔
156
        if err != nil {
1✔
UNCOV
157
                logger.Error(err, "can't create handler")
×
UNCOV
158
                return
×
UNCOV
159
        }
×
160

161
        h.addOperandObject(handler, hc)
1✔
162

1✔
163
        h.operands = append(h.operands, handler)
1✔
164
}
165

166
func (h *OperandHandler) Ensure(req *common.HcoRequest) error {
1✔
167
        for _, handler := range h.operands {
2✔
168
                res := handler.ensure(req)
1✔
169
                if res.Err != nil {
2✔
170
                        req.Logger.Error(res.Err, "failed to ensure an operand")
1✔
171

1✔
172
                        req.ComponentUpgradeInProgress = false
1✔
173
                        req.Conditions.SetStatusCondition(metav1.Condition{
1✔
174
                                Type:               hcov1beta1.ConditionReconcileComplete,
1✔
175
                                Status:             metav1.ConditionFalse,
1✔
176
                                Reason:             reconcileFailed,
1✔
177
                                Message:            fmt.Sprintf("Error while reconciling: %v", res.Err),
1✔
178
                                ObservedGeneration: req.Instance.Generation,
1✔
179
                        })
1✔
180
                        return res.Err
1✔
181
                }
1✔
182

183
                if res.Created {
2✔
184
                        h.eventEmitter.EmitEvent(req.Instance, corev1.EventTypeNormal, "Created", fmt.Sprintf("Created %s %s", res.Type, res.Name))
1✔
185
                } else if res.Updated {
2✔
186
                        h.handleUpdatedOperand(req, res)
×
187
                } else if res.Deleted {
2✔
188
                        h.eventEmitter.EmitEvent(req.Instance, corev1.EventTypeNormal, "Killing", fmt.Sprintf("Removed %s %s", res.Type, res.Name))
1✔
189
                }
1✔
190

191
                req.ComponentUpgradeInProgress = req.ComponentUpgradeInProgress && res.UpgradeDone
1✔
192
        }
193
        return nil
1✔
194

195
}
196

197
func (h *OperandHandler) handleUpdatedOperand(req *common.HcoRequest, res *EnsureResult) {
×
198
        if !res.Overwritten {
×
199
                h.eventEmitter.EmitEvent(req.Instance, corev1.EventTypeNormal, "Updated", fmt.Sprintf("Updated %s %s", res.Type, res.Name))
×
200
        } else {
×
201
                h.eventEmitter.EmitEvent(req.Instance, corev1.EventTypeWarning, "Overwritten", fmt.Sprintf("Overwritten %s %s", res.Type, res.Name))
×
202
                if !req.UpgradeMode {
×
203
                        metrics.IncOverwrittenModifications(res.Type, res.Name)
×
204
                }
×
205
        }
206
}
207

208
func (h *OperandHandler) EnsureDeleted(req *common.HcoRequest) error {
1✔
209

1✔
210
        tCtx, cancel := context.WithTimeout(req.Ctx, deleteTimeOut)
1✔
211
        defer cancel()
1✔
212

1✔
213
        resources := []client.Object{
1✔
214
                NewKubeVirtWithNameOnly(req.Instance),
1✔
215
                NewCDIWithNameOnly(req.Instance),
1✔
216
                NewNetworkAddonsWithNameOnly(req.Instance),
1✔
217
                NewSSPWithNameOnly(req.Instance),
1✔
218
                NewConsoleCLIDownload(req.Instance),
1✔
219
                NewAAQWithNameOnly(req.Instance),
1✔
220
        }
1✔
221

1✔
222
        resources = append(resources, h.objects...)
1✔
223

1✔
224
        eg, egCtx := errgroup.WithContext(tCtx)
1✔
225

1✔
226
        for _, res := range resources {
2✔
227
                func(o client.Object) {
2✔
228
                        eg.Go(func() error {
2✔
229
                                deleted, err := hcoutil.EnsureDeleted(egCtx, h.client, o, req.Instance.Name, req.Logger, false, true, true)
1✔
230
                                if err != nil {
2✔
231
                                        req.Logger.Error(err, "Failed to manually delete objects")
1✔
232
                                        errT := ErrHCOUninstall
1✔
233
                                        errMsg := uninstallHCOErrorMsg
1✔
234
                                        switch o.(type) {
1✔
235
                                        case *kubevirtcorev1.KubeVirt:
1✔
236
                                                errT = ErrVirtUninstall
1✔
237
                                                errMsg = uninstallVirtErrorMsg + err.Error()
1✔
238
                                        case *cdiv1beta1.CDI:
1✔
239
                                                errT = ErrCDIUninstall
1✔
240
                                                errMsg = uninstallCDIErrorMsg + err.Error()
1✔
241
                                        }
242

243
                                        h.eventEmitter.EmitEvent(req.Instance, corev1.EventTypeWarning, errT, errMsg)
1✔
244
                                        return err
1✔
245
                                } else if deleted {
2✔
246
                                        key := client.ObjectKeyFromObject(o)
1✔
247
                                        h.eventEmitter.EmitEvent(req.Instance, corev1.EventTypeNormal, "Killing", fmt.Sprintf("Removed %s %s", o.GetObjectKind().GroupVersionKind().Kind, key.Name))
1✔
248
                                }
1✔
249
                                return nil
1✔
250
                        })
251
                }(res)
252
        }
253

254
        return eg.Wait()
1✔
255
}
256

257
func (h *OperandHandler) Reset() {
×
258
        for _, op := range h.operands {
×
259
                op.reset()
×
260
        }
×
261
}
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

© 2025 Coveralls, Inc