@@ -19,10 +19,12 @@ package controllers
1919import (
2020 "context"
2121
22+ rukpakv1alpha1 "github.com/operator-framework/rukpak/api/v1alpha1"
2223 "k8s.io/apimachinery/pkg/api/equality"
2324 apimeta "k8s.io/apimachinery/pkg/api/meta"
2425 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2526 "k8s.io/apimachinery/pkg/runtime"
27+ "k8s.io/apimachinery/pkg/types"
2628 utilerrors "k8s.io/apimachinery/pkg/util/errors"
2729 ctrl "sigs.k8s.io/controller-runtime"
2830 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -41,10 +43,20 @@ type OperatorReconciler struct {
4143 resolver * resolution.OperatorResolver
4244}
4345
46+ func NewOperatorReconciler (c client.Client , s * runtime.Scheme , r * resolution.OperatorResolver ) * OperatorReconciler {
47+ return & OperatorReconciler {
48+ Client : c ,
49+ Scheme : s ,
50+ resolver : r ,
51+ }
52+ }
53+
4454//+kubebuilder:rbac:groups=operators.operatorframework.io,resources=operators,verbs=get;list;watch;create;update;patch;delete
4555//+kubebuilder:rbac:groups=operators.operatorframework.io,resources=operators/status,verbs=get;update;patch
4656//+kubebuilder:rbac:groups=operators.operatorframework.io,resources=operators/finalizers,verbs=update
4757
58+ //+kubebuilder:rbac:groups=core.rukpak.io,resources=bundledeployments,verbs=get;list;watch;create;update;patch
59+
4860// Reconcile is part of the main kubernetes reconciliation loop which aims to
4961// move the current state of the cluster closer to the desired state.
5062// TODO(user): Modify the Reconcile function to compare the state specified by
@@ -125,8 +137,14 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
125137 if err != nil {
126138 return ctrl.Result {}, err
127139 }
128- // TODO(perdasilva): use bundlePath to stamp out bundle deployment
129- _ = bundlePath
140+ dep , err := r .generateExpectedBundleDeployment (* op , bundlePath )
141+ if err != nil {
142+ return ctrl.Result {}, err
143+ }
144+ // Create bundleDeployment if not found or Update if needed
145+ if err := r .ensureBundleDeployment (ctx , dep ); err != nil {
146+ return ctrl.Result {}, err
147+ }
130148 break
131149 }
132150 }
@@ -145,16 +163,71 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
145163 return ctrl.Result {}, nil
146164}
147165
166+ func (r * OperatorReconciler ) generateExpectedBundleDeployment (o operatorsv1alpha1.Operator , bundlePath string ) (* rukpakv1alpha1.BundleDeployment , error ) {
167+ dep := & rukpakv1alpha1.BundleDeployment {
168+ ObjectMeta : metav1.ObjectMeta {
169+ Name : o .GetName (),
170+ },
171+ Spec : rukpakv1alpha1.BundleDeploymentSpec {
172+ //TODO: Don't assume plain provisioner
173+ ProvisionerClassName : "core-rukpak-io-plain" ,
174+ Template : & rukpakv1alpha1.BundleTemplate {
175+ ObjectMeta : metav1.ObjectMeta {
176+ // TODO: Remove
177+ Labels : map [string ]string {
178+ "app" : "my-bundle" ,
179+ },
180+ },
181+ Spec : rukpakv1alpha1.BundleSpec {
182+ Source : rukpakv1alpha1.BundleSource {
183+ // TODO: Don't assume image type
184+ Type : rukpakv1alpha1 .SourceTypeImage ,
185+ Image : & rukpakv1alpha1.ImageSource {
186+ Ref : bundlePath ,
187+ },
188+ },
189+
190+ //TODO: Don't assume registry provisioner
191+ ProvisionerClassName : "core-rukpak-io-registry" ,
192+ },
193+ },
194+ },
195+ }
196+
197+ if err := ctrl .SetControllerReference (& o , dep , r .Scheme ); err != nil {
198+ return nil , err
199+ }
200+ return dep , nil
201+ }
202+
148203// SetupWithManager sets up the controller with the Manager.
149204func (r * OperatorReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
150- r .resolver = resolution .NewOperatorResolver (mgr .GetClient (), resolution .HardcodedEntitySource )
151-
152205 err := ctrl .NewControllerManagedBy (mgr ).
153206 For (& operatorsv1alpha1.Operator {}).
207+ Owns (& rukpakv1alpha1.BundleDeployment {}).
154208 Complete (r )
155209
156210 if err != nil {
157211 return err
158212 }
159213 return nil
160214}
215+
216+ func (r * OperatorReconciler ) ensureBundleDeployment (ctx context.Context , desiredBundleDeployment * rukpakv1alpha1.BundleDeployment ) error {
217+ existingBundleDeployment := & rukpakv1alpha1.BundleDeployment {}
218+ err := r .Client .Get (ctx , types.NamespacedName {Name : desiredBundleDeployment .GetName ()}, existingBundleDeployment )
219+ if err != nil {
220+ if client .IgnoreNotFound (err ) != nil {
221+ return err
222+ }
223+ return r .Client .Create (ctx , desiredBundleDeployment )
224+ }
225+
226+ // Check if the existing bundleDeployment's spec needs to be updated
227+ if equality .Semantic .DeepEqual (existingBundleDeployment .Spec , desiredBundleDeployment .Spec ) {
228+ return nil
229+ }
230+
231+ existingBundleDeployment .Spec = desiredBundleDeployment .Spec
232+ return r .Client .Update (ctx , existingBundleDeployment )
233+ }
0 commit comments