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

opendefensecloud / solution-arsenal / 24347467865

13 Apr 2026 01:59PM UTC coverage: 72.925% (-1.4%) from 74.334%
24347467865

Pull #395

github

web-flow
Merge 905967457 into 3bbb809bb
Pull Request #395: feat: split of additional resources from Target and refactor rendering

548 of 712 new or added lines in 8 files covered. (76.97%)

11 existing lines in 2 files now uncovered.

2047 of 2807 relevant lines covered (72.92%)

25.51 hits per line

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

78.85
/pkg/controller/release_controller.go
1
// Copyright 2026 BWI GmbH and Solution Arsenal contributors
2
// SPDX-License-Identifier: Apache-2.0
3

4
package controller
5

6
import (
7
        "context"
8

9
        apierrors "k8s.io/apimachinery/pkg/api/errors"
10
        apimeta "k8s.io/apimachinery/pkg/api/meta"
11
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
        "k8s.io/apimachinery/pkg/runtime"
13
        "k8s.io/apimachinery/pkg/types"
14
        "k8s.io/client-go/tools/events"
15
        ctrl "sigs.k8s.io/controller-runtime"
16
        "sigs.k8s.io/controller-runtime/pkg/client"
17

18
        solarv1alpha1 "go.opendefense.cloud/solar/api/solar/v1alpha1"
19
)
20

21
const (
22
        ConditionTypeComponentVersionResolved = "ComponentVersionResolved"
23
)
24

25
// ReleaseReconciler reconciles a Release object.
26
// It validates that the referenced ComponentVersion exists and sets status conditions.
27
// Rendering is handled by the Target controller.
28
type ReleaseReconciler struct {
29
        client.Client
30
        Scheme   *runtime.Scheme
31
        Recorder events.EventRecorder
32
        // WatchNamespace restricts reconciliation to this namespace.
33
        // Should be empty in production (watches all namespaces).
34
        // Intended for use in integration tests only.
35
        // See: https://book.kubebuilder.io/reference/envtest#testing-considerations
36
        WatchNamespace string
37
}
38

39
//+kubebuilder:rbac:groups=solar.opendefense.cloud,resources=releases,verbs=get;list;watch;create;update;patch;delete
40
//+kubebuilder:rbac:groups=solar.opendefense.cloud,resources=releases/status,verbs=get;update;patch
41
//+kubebuilder:rbac:groups=solar.opendefense.cloud,resources=componentversions,verbs=get;list;watch
42
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
43
//+kubebuilder:rbac:groups=events.k8s.io,resources=events,verbs=create;patch
44

45
// Reconcile validates the Release by resolving its ComponentVersion reference.
46
func (r *ReleaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
11✔
47
        log := ctrl.LoggerFrom(ctx)
11✔
48
        ctrlResult := ctrl.Result{}
11✔
49

11✔
50
        log.V(1).Info("Release is being reconciled", "req", req)
11✔
51

11✔
52
        if r.WatchNamespace != "" && req.Namespace != r.WatchNamespace {
11✔
UNCOV
53
                return ctrlResult, nil
×
UNCOV
54
        }
×
55

56
        // Fetch the Release instance
57
        res := &solarv1alpha1.Release{}
11✔
58
        if err := r.Get(ctx, req.NamespacedName, res); err != nil {
11✔
UNCOV
59
                if apierrors.IsNotFound(err) {
×
UNCOV
60
                        return ctrlResult, nil
×
UNCOV
61
                }
×
62

63
                return ctrlResult, errLogAndWrap(log, err, "failed to get object")
×
64
        }
65

66
        // Resolve ComponentVersion
67
        cvRef := types.NamespacedName{
11✔
68
                Name:      res.Spec.ComponentVersionRef.Name,
11✔
69
                Namespace: res.Namespace,
11✔
70
        }
11✔
71
        cv := &solarv1alpha1.ComponentVersion{}
11✔
72
        if err := r.Get(ctx, cvRef, cv); err != nil {
14✔
73
                if apierrors.IsNotFound(err) {
6✔
74
                        changed := apimeta.SetStatusCondition(&res.Status.Conditions, metav1.Condition{
3✔
75
                                Type:               ConditionTypeComponentVersionResolved,
3✔
76
                                Status:             metav1.ConditionFalse,
3✔
77
                                ObservedGeneration: res.Generation,
3✔
78
                                Reason:             "NotFound",
3✔
79
                                Message:            "ComponentVersion not found: " + res.Spec.ComponentVersionRef.Name,
3✔
80
                        })
3✔
81
                        if changed {
5✔
82
                                if err := r.Status().Update(ctx, res); err != nil {
2✔
NEW
83
                                        return ctrlResult, errLogAndWrap(log, err, "failed to update status")
×
NEW
84
                                }
×
85
                        }
86

87
                        return ctrlResult, nil
3✔
88
                }
89

NEW
90
                return ctrlResult, errLogAndWrap(log, err, "failed to get ComponentVersion")
×
91
        }
92

93
        // ComponentVersion found — set resolved condition
94
        changed := apimeta.SetStatusCondition(&res.Status.Conditions, metav1.Condition{
8✔
95
                Type:               ConditionTypeComponentVersionResolved,
8✔
96
                Status:             metav1.ConditionTrue,
8✔
97
                ObservedGeneration: res.Generation,
8✔
98
                Reason:             "Resolved",
8✔
99
                Message:            "ComponentVersion resolved: " + cv.Name,
8✔
100
        })
8✔
101
        if changed {
12✔
102
                if err := r.Status().Update(ctx, res); err != nil {
4✔
103
                        return ctrlResult, errLogAndWrap(log, err, "failed to update status")
×
104
                }
×
105
        }
106

107
        return ctrlResult, nil
8✔
108
}
109

110
// SetupWithManager sets up the controller with the Manager.
111
func (r *ReleaseReconciler) SetupWithManager(mgr ctrl.Manager) error {
1✔
112
        return ctrl.NewControllerManagedBy(mgr).
1✔
113
                For(&solarv1alpha1.Release{}).
1✔
114
                Complete(r)
1✔
115
}
1✔
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