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

k8snetworkplumbingwg / sriov-network-operator / 3751025296

pending completion
3751025296

Pull #365

github

GitHub
Merge 421284b55 into 788d76f7e
Pull Request #365: Implementation for new systemd configuration method

958 of 958 new or added lines in 18 files covered. (100.0%)

1971 of 8330 relevant lines covered (23.66%)

0.27 hits per line

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

40.36
/api/v1/helper.go
1
package v1
2

3
import (
4
        "context"
5
        "encoding/json"
6
        "fmt"
7
        "os"
8
        "regexp"
9
        "sort"
10
        "strconv"
11
        "strings"
12

13
        corev1 "k8s.io/api/core/v1"
14
        "k8s.io/apimachinery/pkg/api/errors"
15
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
        uns "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
17
        "k8s.io/apimachinery/pkg/types"
18
        "k8s.io/client-go/kubernetes"
19
        "sigs.k8s.io/controller-runtime/pkg/client"
20
        logf "sigs.k8s.io/controller-runtime/pkg/log"
21

22
        netattdefv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
23
        render "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render"
24
)
25

26
const (
27
        LASTNETWORKNAMESPACE    = "operator.sriovnetwork.openshift.io/last-network-namespace"
28
        NETATTDEFFINALIZERNAME  = "netattdef.finalizers.sriovnetwork.openshift.io"
29
        POOLCONFIGFINALIZERNAME = "poolconfig.finalizers.sriovnetwork.openshift.io"
30
        ESwithModeLegacy        = "legacy"
31
        ESwithModeSwitchDev     = "switchdev"
32

33
        SriovCniStateEnable  = "enable"
34
        SriovCniStateDisable = "disable"
35
        SriovCniStateAuto    = "auto"
36
        SriovCniStateOff     = "off"
37
        SriovCniStateOn      = "on"
38
        SriovCniIpamEmpty    = "\"ipam\":{}"
39
)
40

41
const invalidVfIndex = -1
42

43
var ManifestsPath = "./bindata/manifests/cni-config"
44
var log = logf.Log.WithName("sriovnetwork")
45

46
// NicIDMap contains supported mapping of IDs with each in the format of:
47
// Vendor ID, Physical Function Device ID, Virtual Function Device ID
48
var NicIDMap = []string{}
49

50
// NetFilterType Represents the NetFilter tags to be used
51
type NetFilterType int
52

53
const (
54
        // OpenstackNetworkID network UUID
55
        OpenstackNetworkID NetFilterType = iota
56

57
        SupportedNicIDConfigmap = "supported-nic-ids"
58
)
59

60
type ConfigurationModeType string
61

62
const (
63
        DaemonConfigurationMode  = "daemon"
64
        SystemdConfigurationMode = "systemd"
65
)
66

67
func (e NetFilterType) String() string {
×
68
        switch e {
×
69
        case OpenstackNetworkID:
×
70
                return "openstack/NetworkID"
×
71
        default:
×
72
                return fmt.Sprintf("%d", int(e))
×
73
        }
74
}
75

76
func InitNicIDMapFromConfigMap(client kubernetes.Interface, namespace string) error {
1✔
77
        cm, err := client.CoreV1().ConfigMaps(namespace).Get(
1✔
78
                context.Background(),
1✔
79
                SupportedNicIDConfigmap,
1✔
80
                metav1.GetOptions{},
1✔
81
        )
1✔
82
        // if the configmap does not exist, return false
1✔
83
        if err != nil {
1✔
84
                return err
×
85
        }
×
86
        for _, v := range cm.Data {
2✔
87
                NicIDMap = append(NicIDMap, v)
1✔
88
        }
1✔
89

90
        return nil
1✔
91
}
92

93
func InitNicIDMapFromList(idList []string) {
×
94
        NicIDMap = append(NicIDMap, idList...)
×
95
}
×
96

97
func IsSupportedVendor(vendorID string) bool {
1✔
98
        for _, n := range NicIDMap {
2✔
99
                ids := strings.Split(n, " ")
1✔
100
                if vendorID == ids[0] {
2✔
101
                        return true
1✔
102
                }
1✔
103
        }
104
        return false
1✔
105
}
106

107
func IsSupportedDevice(deviceID string) bool {
1✔
108
        for _, n := range NicIDMap {
2✔
109
                ids := strings.Split(n, " ")
1✔
110
                if deviceID == ids[1] {
1✔
111
                        return true
×
112
                }
×
113
        }
114
        return false
1✔
115
}
116

117
func IsSupportedModel(vendorID, deviceID string) bool {
1✔
118
        for _, n := range NicIDMap {
2✔
119
                ids := strings.Split(n, " ")
1✔
120
                if vendorID == ids[0] && deviceID == ids[1] {
2✔
121
                        return true
1✔
122
                }
1✔
123
        }
124
        log.Info("IsSupportedModel():", "Unsupported model:", "vendorId:", vendorID, "deviceId:", deviceID)
1✔
125
        return false
1✔
126
}
127

128
func IsVfSupportedModel(vendorID, deviceID string) bool {
1✔
129
        for _, n := range NicIDMap {
2✔
130
                ids := strings.Split(n, " ")
1✔
131
                if vendorID == ids[0] && deviceID == ids[2] {
2✔
132
                        return true
1✔
133
                }
1✔
134
        }
135
        log.Info("IsVfSupportedModel():", "Unsupported VF model:", "vendorId:", vendorID, "deviceId:", deviceID)
×
136
        return false
×
137
}
138

139
func IsEnabledUnsupportedVendor(vendorID string, unsupportedNicIDMap map[string]string) bool {
×
140
        for _, n := range unsupportedNicIDMap {
×
141
                if IsValidPciString(n) {
×
142
                        ids := strings.Split(n, " ")
×
143
                        if vendorID == ids[0] {
×
144
                                return true
×
145
                        }
×
146
                }
147
        }
148
        return false
×
149
}
150

151
func IsValidPciString(nicIDString string) bool {
×
152
        ids := strings.Split(nicIDString, " ")
×
153

×
154
        if len(ids) != 3 {
×
155
                log.Info("IsValidPciString(): ", nicIDString)
×
156
                return false
×
157
        }
×
158

159
        if len(ids[0]) != 4 {
×
160
                log.Info("IsValidPciString():", "Invalid vendor PciId ", ids[0])
×
161
                return false
×
162
        }
×
163
        if _, err := strconv.ParseInt(ids[0], 16, 32); err != nil {
×
164
                log.Info("IsValidPciString():", "Invalid vendor PciId ", ids[0])
×
165
        }
×
166

167
        if len(ids[1]) != 4 {
×
168
                log.Info("IsValidPciString():", "Invalid PciId of PF ", ids[1])
×
169
                return false
×
170
        }
×
171
        if _, err := strconv.ParseInt(ids[1], 16, 32); err != nil {
×
172
                log.Info("IsValidPciString():", "Invalid PciId of PF ", ids[1])
×
173
        }
×
174

175
        if len(ids[2]) != 4 {
×
176
                log.Info("IsValidPciString():", "Invalid PciId of VF ", ids[2])
×
177
                return false
×
178
        }
×
179
        if _, err := strconv.ParseInt(ids[2], 16, 32); err != nil {
×
180
                log.Info("IsValidPciString():", "Invalid PciId of VF ", ids[2])
×
181
        }
×
182

183
        return true
×
184
}
185

186
func GetSupportedVfIds() []string {
1✔
187
        var vfIds []string
1✔
188
        for _, n := range NicIDMap {
2✔
189
                ids := strings.Split(n, " ")
1✔
190
                vfID := "0x" + ids[2]
1✔
191
                if !StringInArray(vfID, vfIds) {
2✔
192
                        vfIds = append(vfIds, vfID)
1✔
193
                }
1✔
194
        }
195
        // return a sorted slice so that udev rule is stable
196
        sort.Slice(vfIds, func(i, j int) bool {
2✔
197
                ip, _ := strconv.ParseInt(vfIds[i], 0, 32)
1✔
198
                jp, _ := strconv.ParseInt(vfIds[j], 0, 32)
1✔
199
                return ip < jp
1✔
200
        })
1✔
201
        return vfIds
1✔
202
}
203

204
func GetVfDeviceID(deviceID string) string {
×
205
        for _, n := range NicIDMap {
×
206
                ids := strings.Split(n, " ")
×
207
                if deviceID == ids[1] {
×
208
                        return ids[2]
×
209
                }
×
210
        }
211
        return ""
×
212
}
213

214
type ByPriority []SriovNetworkNodePolicy
215

216
func (a ByPriority) Len() int {
×
217
        return len(a)
×
218
}
×
219

220
func (a ByPriority) Less(i, j int) bool {
×
221
        if a[i].Spec.Priority != a[j].Spec.Priority {
×
222
                return a[i].Spec.Priority > a[j].Spec.Priority
×
223
        }
×
224
        return a[i].GetName() < a[j].GetName()
×
225
}
226

227
func (a ByPriority) Swap(i, j int) {
×
228
        a[i], a[j] = a[j], a[i]
×
229
}
×
230

231
// Match check if node is selected by NodeSelector
232
func (p *SriovNetworkNodePolicy) Selected(node *corev1.Node) bool {
×
233
        for k, v := range p.Spec.NodeSelector {
×
234
                if nv, ok := node.Labels[k]; ok && nv == v {
×
235
                        continue
×
236
                }
237
                return false
×
238
        }
239
        log.Info("Selected():", "node", node.Name)
×
240
        return true
×
241
}
242

243
func StringInArray(val string, array []string) bool {
1✔
244
        for i := range array {
2✔
245
                if array[i] == val {
2✔
246
                        return true
1✔
247
                }
1✔
248
        }
249
        return false
1✔
250
}
251

252
func RemoveString(s string, slice []string) (result []string, found bool) {
1✔
253
        if len(slice) != 0 {
2✔
254
                for _, item := range slice {
2✔
255
                        if item == s {
2✔
256
                                found = true
1✔
257
                                continue
1✔
258
                        }
259
                        result = append(result, item)
×
260
                }
261
        }
262
        return
1✔
263
}
264

265
func UniqueAppend(inSlice []string, strings ...string) []string {
×
266
        for _, s := range strings {
×
267
                if !StringInArray(s, inSlice) {
×
268
                        inSlice = append(inSlice, s)
×
269
                }
×
270
        }
271
        return inSlice
×
272
}
273

274
// Apply policy to SriovNetworkNodeState CR
275
func (p *SriovNetworkNodePolicy) Apply(state *SriovNetworkNodeState, equalPriority bool) error {
×
276
        s := p.Spec.NicSelector
×
277
        if s.Vendor == "" && s.DeviceID == "" && len(s.RootDevices) == 0 && len(s.PfNames) == 0 &&
×
278
                len(s.NetFilter) == 0 {
×
279
                // Empty NicSelector match none
×
280
                return nil
×
281
        }
×
282
        for _, iface := range state.Status.Interfaces {
×
283
                if s.Selected(&iface) {
×
284
                        log.Info("Update interface", "name:", iface.Name)
×
285
                        result := Interface{
×
286
                                PciAddress:  iface.PciAddress,
×
287
                                Mtu:         p.Spec.Mtu,
×
288
                                Name:        iface.Name,
×
289
                                LinkType:    p.Spec.LinkType,
×
290
                                EswitchMode: p.Spec.EswitchMode,
×
291
                                NumVfs:      p.Spec.NumVfs,
×
292
                        }
×
293
                        if p.Spec.NumVfs > 0 {
×
294
                                group, err := p.generateVfGroup(&iface)
×
295
                                if err != nil {
×
296
                                        return err
×
297
                                }
×
298
                                result.VfGroups = []VfGroup{*group}
×
299
                                found := false
×
300
                                for i := range state.Spec.Interfaces {
×
301
                                        if state.Spec.Interfaces[i].PciAddress == result.PciAddress {
×
302
                                                found = true
×
303
                                                state.Spec.Interfaces[i].mergeConfigs(&result, equalPriority)
×
304
                                                state.Spec.Interfaces[i] = result
×
305
                                                break
×
306
                                        }
307
                                }
308
                                if !found {
×
309
                                        state.Spec.Interfaces = append(state.Spec.Interfaces, result)
×
310
                                }
×
311
                        }
312
                }
313
        }
314
        return nil
×
315
}
316

317
// mergeConfigs merges configs from multiple polices where the last one has the
318
// highest priority. This merge is dependent on: 1. SR-IOV partition is
319
// configured with the #-notation in pfName, 2. The VF groups are
320
// non-overlapping or SR-IOV policies have the same priority.
321
func (iface Interface) mergeConfigs(input *Interface, equalPriority bool) {
×
322
        m := false
×
323
        // merge VF groups (input.VfGroups already contains the highest priority):
×
324
        // - skip group with same ResourceName,
×
325
        // - skip overlapping groups (use only highest priority)
×
326
        for _, gr := range iface.VfGroups {
×
327
                if gr.ResourceName == input.VfGroups[0].ResourceName || gr.isVFRangeOverlapping(input.VfGroups[0]) {
×
328
                        continue
×
329
                }
330
                m = true
×
331
                input.VfGroups = append(input.VfGroups, gr)
×
332
        }
333

334
        if !equalPriority && !m {
×
335
                return
×
336
        }
×
337

338
        // mtu configuration we take the highest value
339
        if input.Mtu < iface.Mtu {
×
340
                input.Mtu = iface.Mtu
×
341
        }
×
342
        if input.NumVfs < iface.NumVfs {
×
343
                input.NumVfs = iface.NumVfs
×
344
        }
×
345
}
346

347
func (gr VfGroup) isVFRangeOverlapping(group VfGroup) bool {
×
348
        rngSt, rngEnd, err := parseRange(gr.VfRange)
×
349
        if err != nil {
×
350
                return false
×
351
        }
×
352
        rngSt2, rngEnd2, err := parseRange(group.VfRange)
×
353
        if err != nil {
×
354
                return false
×
355
        }
×
356
        // compare minimal range has overlap
357
        if rngSt < rngSt2 {
×
358
                return IndexInRange(rngSt2, gr.VfRange) || IndexInRange(rngEnd2, gr.VfRange)
×
359
        }
×
360
        return IndexInRange(rngSt, group.VfRange) || IndexInRange(rngEnd, group.VfRange)
×
361
}
362

363
func (p *SriovNetworkNodePolicy) generateVfGroup(iface *InterfaceExt) (*VfGroup, error) {
×
364
        var err error
×
365
        pfName := ""
×
366
        var rngStart, rngEnd int
×
367
        found := false
×
368
        for _, selector := range p.Spec.NicSelector.PfNames {
×
369
                pfName, rngStart, rngEnd, err = ParsePFName(selector)
×
370
                if err != nil {
×
371
                        log.Error(err, "Unable to parse PF Name.")
×
372
                        return nil, err
×
373
                }
×
374
                if pfName == iface.Name {
×
375
                        found = true
×
376
                        if rngStart == invalidVfIndex && rngEnd == invalidVfIndex {
×
377
                                rngStart, rngEnd = 0, p.Spec.NumVfs-1
×
378
                        }
×
379
                        break
×
380
                }
381
        }
382
        if !found {
×
383
                // assign the default vf index range if the pfName is not specified by the nicSelector
×
384
                rngStart, rngEnd = 0, p.Spec.NumVfs-1
×
385
        }
×
386
        rng := strconv.Itoa(rngStart) + "-" + strconv.Itoa(rngEnd)
×
387
        return &VfGroup{
×
388
                ResourceName: p.Spec.ResourceName,
×
389
                DeviceType:   p.Spec.DeviceType,
×
390
                VfRange:      rng,
×
391
                PolicyName:   p.GetName(),
×
392
                Mtu:          p.Spec.Mtu,
×
393
                IsRdma:       p.Spec.IsRdma,
×
394
        }, nil
×
395
}
396

397
func IndexInRange(i int, r string) bool {
1✔
398
        rngSt, rngEnd, err := parseRange(r)
1✔
399
        if err != nil {
1✔
400
                return false
×
401
        }
×
402
        if i <= rngEnd && i >= rngSt {
2✔
403
                return true
1✔
404
        }
1✔
405
        return false
×
406
}
407

408
func parseRange(r string) (rngSt, rngEnd int, err error) {
1✔
409
        rng := strings.Split(r, "-")
1✔
410
        rngSt, err = strconv.Atoi(rng[0])
1✔
411
        if err != nil {
1✔
412
                return
×
413
        }
×
414
        rngEnd, err = strconv.Atoi(rng[1])
1✔
415
        if err != nil {
1✔
416
                return
×
417
        }
×
418
        return
1✔
419
}
420

421
// Parse PF name with VF range
422
func ParsePFName(name string) (ifName string, rngSt, rngEnd int, err error) {
1✔
423
        rngSt, rngEnd = invalidVfIndex, invalidVfIndex
1✔
424
        if strings.Contains(name, "#") {
2✔
425
                fields := strings.Split(name, "#")
1✔
426
                ifName = fields[0]
1✔
427
                rngSt, rngEnd, err = parseRange(fields[1])
1✔
428
        } else {
1✔
429
                ifName = name
×
430
        }
×
431
        return
1✔
432
}
433

434
func (selector *SriovNetworkNicSelector) Selected(iface *InterfaceExt) bool {
×
435
        if selector.Vendor != "" && selector.Vendor != iface.Vendor {
×
436
                return false
×
437
        }
×
438
        if selector.DeviceID != "" && selector.DeviceID != iface.DeviceID {
×
439
                return false
×
440
        }
×
441
        if len(selector.RootDevices) > 0 && !StringInArray(iface.PciAddress, selector.RootDevices) {
×
442
                return false
×
443
        }
×
444
        if len(selector.PfNames) > 0 {
×
445
                var pfNames []string
×
446
                for _, p := range selector.PfNames {
×
447
                        if strings.Contains(p, "#") {
×
448
                                fields := strings.Split(p, "#")
×
449
                                pfNames = append(pfNames, fields[0])
×
450
                        } else {
×
451
                                pfNames = append(pfNames, p)
×
452
                        }
×
453
                }
454
                if !StringInArray(iface.Name, pfNames) {
×
455
                        return false
×
456
                }
×
457
        }
458
        if selector.NetFilter != "" && !NetFilterMatch(selector.NetFilter, iface.NetFilter) {
×
459
                return false
×
460
        }
×
461

462
        return true
×
463
}
464

465
func (s *SriovNetworkNodeState) GetInterfaceStateByPciAddress(addr string) *InterfaceExt {
×
466
        for _, iface := range s.Status.Interfaces {
×
467
                if addr == iface.PciAddress {
×
468
                        return &iface
×
469
                }
×
470
        }
471
        return nil
×
472
}
473

474
func (s *SriovNetworkNodeState) GetDriverByPciAddress(addr string) string {
×
475
        for _, iface := range s.Status.Interfaces {
×
476
                if addr == iface.PciAddress {
×
477
                        return iface.Driver
×
478
                }
×
479
        }
480
        return ""
×
481
}
482

483
// RenderNetAttDef renders a net-att-def for ib-sriov CNI
484
func (cr *SriovIBNetwork) RenderNetAttDef() (*uns.Unstructured, error) {
1✔
485
        logger := log.WithName("renderNetAttDef")
1✔
486
        logger.Info("Start to render IB SRIOV CNI NetworkAttachementDefinition")
1✔
487

1✔
488
        // render RawCNIConfig manifests
1✔
489
        data := render.MakeRenderData()
1✔
490
        data.Data["CniType"] = "ib-sriov"
1✔
491
        data.Data["SriovNetworkName"] = cr.Name
1✔
492
        if cr.Spec.NetworkNamespace == "" {
2✔
493
                data.Data["SriovNetworkNamespace"] = cr.Namespace
1✔
494
        } else {
2✔
495
                data.Data["SriovNetworkNamespace"] = cr.Spec.NetworkNamespace
1✔
496
        }
1✔
497
        data.Data["SriovCniResourceName"] = os.Getenv("RESOURCE_PREFIX") + "/" + cr.Spec.ResourceName
1✔
498

1✔
499
        data.Data["StateConfigured"] = true
1✔
500
        switch cr.Spec.LinkState {
1✔
501
        case SriovCniStateEnable:
1✔
502
                data.Data["SriovCniState"] = SriovCniStateEnable
1✔
503
        case SriovCniStateDisable:
×
504
                data.Data["SriovCniState"] = SriovCniStateDisable
×
505
        case SriovCniStateAuto:
×
506
                data.Data["SriovCniState"] = SriovCniStateAuto
×
507
        default:
1✔
508
                data.Data["StateConfigured"] = false
1✔
509
        }
510

511
        if cr.Spec.Capabilities == "" {
2✔
512
                data.Data["CapabilitiesConfigured"] = false
1✔
513
        } else {
1✔
514
                data.Data["CapabilitiesConfigured"] = true
×
515
                data.Data["SriovCniCapabilities"] = cr.Spec.Capabilities
×
516
        }
×
517

518
        if cr.Spec.IPAM != "" {
2✔
519
                data.Data["SriovCniIpam"] = "\"ipam\":" + strings.Join(strings.Fields(cr.Spec.IPAM), "")
1✔
520
        } else {
2✔
521
                data.Data["SriovCniIpam"] = SriovCniIpamEmpty
1✔
522
        }
1✔
523

524
        // metaplugins for the infiniband cni
525
        data.Data["MetaPluginsConfigured"] = false
1✔
526
        if cr.Spec.MetaPluginsConfig != "" {
1✔
527
                data.Data["MetaPluginsConfigured"] = true
×
528
                data.Data["MetaPlugins"] = cr.Spec.MetaPluginsConfig
×
529
        }
×
530

531
        objs, err := render.RenderDir(ManifestsPath, &data)
1✔
532
        if err != nil {
1✔
533
                return nil, err
×
534
        }
×
535
        for _, obj := range objs {
2✔
536
                raw, _ := json.Marshal(obj)
1✔
537
                logger.Info("render NetworkAttachementDefinition output", "raw", string(raw))
1✔
538
        }
1✔
539
        return objs[0], nil
1✔
540
}
541

542
// DeleteNetAttDef deletes the generated net-att-def CR
543
func (cr *SriovIBNetwork) DeleteNetAttDef(c client.Client) error {
1✔
544
        // Fetch the NetworkAttachmentDefinition instance
1✔
545
        instance := &netattdefv1.NetworkAttachmentDefinition{}
1✔
546
        namespace := cr.GetNamespace()
1✔
547
        if cr.Spec.NetworkNamespace != "" {
2✔
548
                namespace = cr.Spec.NetworkNamespace
1✔
549
        }
1✔
550
        err := c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: cr.GetName()}, instance)
1✔
551
        if err != nil {
1✔
552
                if errors.IsNotFound(err) {
×
553
                        return nil
×
554
                }
×
555
                return err
×
556
        }
557
        err = c.Delete(context.TODO(), instance)
1✔
558
        if err != nil {
1✔
559
                return err
×
560
        }
×
561
        return nil
1✔
562
}
563

564
// RenderNetAttDef renders a net-att-def for sriov CNI
565
func (cr *SriovNetwork) RenderNetAttDef() (*uns.Unstructured, error) {
1✔
566
        logger := log.WithName("renderNetAttDef")
1✔
567
        logger.Info("Start to render SRIOV CNI NetworkAttachementDefinition")
1✔
568

1✔
569
        // render RawCNIConfig manifests
1✔
570
        data := render.MakeRenderData()
1✔
571
        data.Data["CniType"] = "sriov"
1✔
572
        data.Data["SriovNetworkName"] = cr.Name
1✔
573
        if cr.Spec.NetworkNamespace == "" {
2✔
574
                data.Data["SriovNetworkNamespace"] = cr.Namespace
1✔
575
        } else {
2✔
576
                data.Data["SriovNetworkNamespace"] = cr.Spec.NetworkNamespace
1✔
577
        }
1✔
578
        data.Data["SriovCniResourceName"] = os.Getenv("RESOURCE_PREFIX") + "/" + cr.Spec.ResourceName
1✔
579
        data.Data["SriovCniVlan"] = cr.Spec.Vlan
1✔
580

1✔
581
        if cr.Spec.VlanQoS <= 7 && cr.Spec.VlanQoS >= 0 {
2✔
582
                data.Data["VlanQoSConfigured"] = true
1✔
583
                data.Data["SriovCniVlanQoS"] = cr.Spec.VlanQoS
1✔
584
        } else {
1✔
585
                data.Data["VlanQoSConfigured"] = false
×
586
        }
×
587

588
        if cr.Spec.Capabilities == "" {
2✔
589
                data.Data["CapabilitiesConfigured"] = false
1✔
590
        } else {
1✔
591
                data.Data["CapabilitiesConfigured"] = true
×
592
                data.Data["SriovCniCapabilities"] = cr.Spec.Capabilities
×
593
        }
×
594

595
        data.Data["SpoofChkConfigured"] = true
1✔
596
        switch cr.Spec.SpoofChk {
1✔
597
        case SriovCniStateOff:
×
598
                data.Data["SriovCniSpoofChk"] = SriovCniStateOff
×
599
        case SriovCniStateOn:
1✔
600
                data.Data["SriovCniSpoofChk"] = SriovCniStateOn
1✔
601
        default:
1✔
602
                data.Data["SpoofChkConfigured"] = false
1✔
603
        }
604

605
        data.Data["TrustConfigured"] = true
1✔
606
        switch cr.Spec.Trust {
1✔
607
        case SriovCniStateOn:
1✔
608
                data.Data["SriovCniTrust"] = SriovCniStateOn
1✔
609
        case SriovCniStateOff:
×
610
                data.Data["SriovCniTrust"] = SriovCniStateOff
×
611
        default:
1✔
612
                data.Data["TrustConfigured"] = false
1✔
613
        }
614

615
        data.Data["StateConfigured"] = true
1✔
616
        switch cr.Spec.LinkState {
1✔
617
        case SriovCniStateEnable:
×
618
                data.Data["SriovCniState"] = SriovCniStateEnable
×
619
        case SriovCniStateDisable:
×
620
                data.Data["SriovCniState"] = SriovCniStateDisable
×
621
        case SriovCniStateAuto:
×
622
                data.Data["SriovCniState"] = SriovCniStateAuto
×
623
        default:
1✔
624
                data.Data["StateConfigured"] = false
1✔
625
        }
626

627
        data.Data["MinTxRateConfigured"] = false
1✔
628
        if cr.Spec.MinTxRate != nil {
1✔
629
                if *cr.Spec.MinTxRate >= 0 {
×
630
                        data.Data["MinTxRateConfigured"] = true
×
631
                        data.Data["SriovCniMinTxRate"] = *cr.Spec.MinTxRate
×
632
                }
×
633
        }
634

635
        data.Data["MaxTxRateConfigured"] = false
1✔
636
        if cr.Spec.MaxTxRate != nil {
1✔
637
                if *cr.Spec.MaxTxRate >= 0 {
×
638
                        data.Data["MaxTxRateConfigured"] = true
×
639
                        data.Data["SriovCniMaxTxRate"] = *cr.Spec.MaxTxRate
×
640
                }
×
641
        }
642

643
        if cr.Spec.IPAM != "" {
2✔
644
                data.Data["SriovCniIpam"] = "\"ipam\":" + strings.Join(strings.Fields(cr.Spec.IPAM), "")
1✔
645
        } else {
1✔
646
                data.Data["SriovCniIpam"] = SriovCniIpamEmpty
×
647
        }
×
648

649
        data.Data["MetaPluginsConfigured"] = false
1✔
650
        if cr.Spec.MetaPluginsConfig != "" {
1✔
651
                data.Data["MetaPluginsConfigured"] = true
×
652
                data.Data["MetaPlugins"] = cr.Spec.MetaPluginsConfig
×
653
        }
×
654

655
        objs, err := render.RenderDir(ManifestsPath, &data)
1✔
656
        if err != nil {
1✔
657
                return nil, err
×
658
        }
×
659
        for _, obj := range objs {
2✔
660
                raw, _ := json.Marshal(obj)
1✔
661
                logger.Info("render NetworkAttachementDefinition output", "raw", string(raw))
1✔
662
        }
1✔
663
        return objs[0], nil
1✔
664
}
665

666
// DeleteNetAttDef deletes the generated net-att-def CR
667
func (cr *SriovNetwork) DeleteNetAttDef(c client.Client) error {
1✔
668
        // Fetch the NetworkAttachmentDefinition instance
1✔
669
        instance := &netattdefv1.NetworkAttachmentDefinition{}
1✔
670
        namespace := cr.GetNamespace()
1✔
671
        if cr.Spec.NetworkNamespace != "" {
2✔
672
                namespace = cr.Spec.NetworkNamespace
1✔
673
        }
1✔
674
        err := c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: cr.GetName()}, instance)
1✔
675
        if err != nil {
1✔
676
                if errors.IsNotFound(err) {
×
677
                        return nil
×
678
                }
×
679
                return err
×
680
        }
681
        err = c.Delete(context.TODO(), instance)
1✔
682
        if err != nil {
1✔
683
                return err
×
684
        }
×
685
        return nil
1✔
686
}
687

688
// NetFilterMatch -- parse netFilter and check for a match
689
func NetFilterMatch(netFilter string, netValue string) (isMatch bool) {
×
690
        logger := log.WithName("NetFilterMatch")
×
691

×
692
        var re = regexp.MustCompile(`(?m)^\s*([^\s]+)\s*:\s*([^\s]+)`)
×
693

×
694
        netFilterResult := re.FindAllStringSubmatch(netFilter, -1)
×
695

×
696
        if netFilterResult == nil {
×
697
                logger.Info("Invalid NetFilter spec...", "netFilter", netFilter)
×
698
                return false
×
699
        }
×
700

701
        netValueResult := re.FindAllStringSubmatch(netValue, -1)
×
702

×
703
        if netValueResult == nil {
×
704
                logger.Info("Invalid netValue...", "netValue", netValue)
×
705
                return false
×
706
        }
×
707

708
        return netFilterResult[0][1] == netValueResult[0][1] && netFilterResult[0][2] == netValueResult[0][2]
×
709
}
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