blob: 0b5059aff229a158052bd65ce8a3cba84f881ad1 [file] [log] [blame]
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +04001/*
2Copyright 2023.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package controllers
18
19import (
20 "bytes"
21 "context"
22 "text/template"
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040023 "time"
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040024
Giorgi Lekveishvili37c6bcd2023-12-20 19:29:32 +040025 "github.com/Masterminds/sprig/v3"
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040026 corev1 "k8s.io/api/core/v1"
27 "k8s.io/apimachinery/pkg/runtime"
28 ctrl "sigs.k8s.io/controller-runtime"
29 "sigs.k8s.io/controller-runtime/pkg/client"
30 "sigs.k8s.io/controller-runtime/pkg/log"
31 "sigs.k8s.io/yaml"
32
33 dodocloudv1 "github.com/giolekva/pcloud/api/v1"
34)
35
36// ResourceRendererReconciler reconciles a ResourceRenderer object
37type ResourceRendererReconciler struct {
38 client.Client
39 Scheme *runtime.Scheme
40}
41
42//+kubebuilder:rbac:groups=dodo.cloud.dodo.cloud,resources=resourcerenderers,verbs=get;list;watch;create;update;patch;delete
43//+kubebuilder:rbac:groups=dodo.cloud.dodo.cloud,resources=resourcerenderers/status,verbs=get;update;patch
44//+kubebuilder:rbac:groups=dodo.cloud.dodo.cloud,resources=resourcerenderers/finalizers,verbs=update
45//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch;delete
46//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete
47
48// Reconcile is part of the main kubernetes reconciliation loop which aims to
49// move the current state of the cluster closer to the desired state.
50// TODO(user): Modify the Reconcile function to compare the state specified by
51// the ResourceRenderer object against the actual cluster state, and then
52// perform operations to make the cluster state reflect the state specified by
53// the user.
54//
55// For more details, check Reconcile and its Result here:
56// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
57func (r *ResourceRendererReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
58 logger := log.FromContext(ctx)
59 logger.Info(req.String())
60
61 resource := &dodocloudv1.ResourceRenderer{}
62 if err := r.Get(context.Background(), client.ObjectKey{
63 Namespace: req.Namespace,
64 Name: req.Name,
65 }, resource); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040066 return ctrl.Result{RequeueAfter: time.Minute}, err
67 }
68 if resource.Status.Ready {
69 return ctrl.Result{}, nil
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040070 }
71 secret := &corev1.Secret{}
72 ns := resource.Spec.SecretNamespace
73 if len(ns) == 0 {
74 ns = req.Namespace
75 }
76 if err := r.Get(context.Background(), client.ObjectKey{
77 Namespace: ns,
78 Name: resource.Spec.SecretName,
79 }, secret); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040080 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040081 }
82 data := make(map[string]string)
83 for key, value := range secret.Data {
84 data[key] = string(value)
85 }
Giorgi Lekveishvili37c6bcd2023-12-20 19:29:32 +040086 tmpl, err := template.New("resource").Funcs(sprig.TxtFuncMap()).Parse(resource.Spec.ResourceTemplate)
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040087 if err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040088 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040089 }
90 var rendered bytes.Buffer
91 if err := tmpl.Execute(&rendered, data); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040092 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040093 }
94 config := &corev1.ConfigMap{}
95 if err := yaml.Unmarshal(rendered.Bytes(), config); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040096 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040097 }
98 if err := r.Create(context.Background(), config); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040099 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +0400100 }
Giorgi Lekveishvili71761892023-06-21 15:03:14 +0400101 resource.Status.Ready = true
102 if err := r.Status().Update(context.Background(), resource); err != nil {
103 return ctrl.Result{RequeueAfter: time.Minute}, err
104 }
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +0400105 return ctrl.Result{}, nil
106}
107
108// SetupWithManager sets up the controller with the Manager.
109func (r *ResourceRendererReconciler) SetupWithManager(mgr ctrl.Manager) error {
110 return ctrl.NewControllerManagedBy(mgr).
111 For(&dodocloudv1.ResourceRenderer{}).
112 Complete(r)
113}