blob: 8a5799628fa2a7018f36aeb18784cbc651eb2d93 [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
25 corev1 "k8s.io/api/core/v1"
26 "k8s.io/apimachinery/pkg/runtime"
27 ctrl "sigs.k8s.io/controller-runtime"
28 "sigs.k8s.io/controller-runtime/pkg/client"
29 "sigs.k8s.io/controller-runtime/pkg/log"
30 "sigs.k8s.io/yaml"
31
32 dodocloudv1 "github.com/giolekva/pcloud/api/v1"
33)
34
35// ResourceRendererReconciler reconciles a ResourceRenderer object
36type ResourceRendererReconciler struct {
37 client.Client
38 Scheme *runtime.Scheme
39}
40
41//+kubebuilder:rbac:groups=dodo.cloud.dodo.cloud,resources=resourcerenderers,verbs=get;list;watch;create;update;patch;delete
42//+kubebuilder:rbac:groups=dodo.cloud.dodo.cloud,resources=resourcerenderers/status,verbs=get;update;patch
43//+kubebuilder:rbac:groups=dodo.cloud.dodo.cloud,resources=resourcerenderers/finalizers,verbs=update
44//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch;delete
45//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete
46
47// Reconcile is part of the main kubernetes reconciliation loop which aims to
48// move the current state of the cluster closer to the desired state.
49// TODO(user): Modify the Reconcile function to compare the state specified by
50// the ResourceRenderer object against the actual cluster state, and then
51// perform operations to make the cluster state reflect the state specified by
52// the user.
53//
54// For more details, check Reconcile and its Result here:
55// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
56func (r *ResourceRendererReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
57 logger := log.FromContext(ctx)
58 logger.Info(req.String())
59
60 resource := &dodocloudv1.ResourceRenderer{}
61 if err := r.Get(context.Background(), client.ObjectKey{
62 Namespace: req.Namespace,
63 Name: req.Name,
64 }, resource); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040065 return ctrl.Result{RequeueAfter: time.Minute}, err
66 }
67 if resource.Status.Ready {
68 return ctrl.Result{}, nil
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040069 }
70 secret := &corev1.Secret{}
71 ns := resource.Spec.SecretNamespace
72 if len(ns) == 0 {
73 ns = req.Namespace
74 }
75 if err := r.Get(context.Background(), client.ObjectKey{
76 Namespace: ns,
77 Name: resource.Spec.SecretName,
78 }, secret); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040079 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040080 }
81 data := make(map[string]string)
82 for key, value := range secret.Data {
83 data[key] = string(value)
84 }
85 tmpl, err := template.New("resource").Parse(resource.Spec.ResourceTemplate)
86 if err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040087 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040088 }
89 var rendered bytes.Buffer
90 if err := tmpl.Execute(&rendered, data); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040091 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040092 }
93 config := &corev1.ConfigMap{}
94 if err := yaml.Unmarshal(rendered.Bytes(), config); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040095 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040096 }
97 if err := r.Create(context.Background(), config); err != nil {
Giorgi Lekveishvili71761892023-06-21 15:03:14 +040098 return ctrl.Result{RequeueAfter: time.Minute}, err
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +040099 }
Giorgi Lekveishvili71761892023-06-21 15:03:14 +0400100 resource.Status.Ready = true
101 if err := r.Status().Update(context.Background(), resource); err != nil {
102 return ctrl.Result{RequeueAfter: time.Minute}, err
103 }
Giorgi Lekveishvilib591eae2023-06-16 12:31:49 +0400104 return ctrl.Result{}, nil
105}
106
107// SetupWithManager sets up the controller with the Manager.
108func (r *ResourceRendererReconciler) SetupWithManager(mgr ctrl.Manager) error {
109 return ctrl.NewControllerManagedBy(mgr).
110 For(&dodocloudv1.ResourceRenderer{}).
111 Complete(r)
112}