diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 3b8dc07..d5e695a 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -20,6 +20,7 @@ rules: - "" resources: - pods + - serviceaccounts - services verbs: - create diff --git a/internal/controller/doclingserve_controller.go b/internal/controller/doclingserve_controller.go index 8f6b21b..48ffcdf 100644 --- a/internal/controller/doclingserve_controller.go +++ b/internal/controller/doclingserve_controller.go @@ -45,7 +45,7 @@ type DoclingServeReconciler struct { // +kubebuilder:rbac:groups=docling.github.io,resources=doclingserves/status,verbs=get;update;patch // +kubebuilder:rbac:groups=docling.github.io,resources=doclingserves/finalizers,verbs=update // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods;services,verbs=update;create;get;list;watch +// +kubebuilder:rbac:groups=core,resources=pods;services;serviceaccounts,verbs=update;create;get;list;watch // +kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=* // Reconcile is part of the main kubernetes reconciliation loop which aims to @@ -73,6 +73,7 @@ func (r *DoclingServeReconciler) Reconcile(ctx context.Context, req ctrl.Request } resourceReconcilers := []reconcilers.Reconciler{ + reconcilers.NewServiceAccountReconciler(r.Client, r.Scheme), reconcilers.NewDeploymentReconciler(r.Client, r.Scheme), reconcilers.NewServiceReconciler(r.Client, r.Scheme), reconcilers.NewRouteReconciler(r.Client, r.Scheme), diff --git a/internal/reconcilers/deployment.go b/internal/reconcilers/deployment.go index 7353f75..6fae9e4 100644 --- a/internal/reconcilers/deployment.go +++ b/internal/reconcilers/deployment.go @@ -46,6 +46,7 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, doclingServe *v1al Labels: labels, }, Spec: corev1.PodSpec{ + ServiceAccountName: serviceAccountName, Containers: []corev1.Container{ { Image: doclingServe.Spec.APIServer.Image, diff --git a/internal/reconcilers/service_account.go b/internal/reconcilers/service_account.go new file mode 100644 index 0000000..57a64b1 --- /dev/null +++ b/internal/reconcilers/service_account.go @@ -0,0 +1,45 @@ +package reconcilers + +import ( + "context" + + "github.io/opdev/docling-operator/api/v1alpha1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +type ServiceAccountReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +const serviceAccountName = "docling-serve" + +func NewServiceAccountReconciler(client client.Client, scheme *runtime.Scheme) *ServiceAccountReconciler { + return &ServiceAccountReconciler{ + Client: client, + Scheme: scheme, + } +} + +func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, doclingServe *v1alpha1.DoclingServe) (bool, error) { + log := logf.FromContext(ctx) + serviceAccount := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: serviceAccountName, Namespace: doclingServe.Namespace}} + _, err := controllerutil.CreateOrUpdate(ctx, r.Client, serviceAccount, func() error { + serviceAccount.Labels = labelsForDocling(doclingServe.Name) + _ = ctrl.SetControllerReference(doclingServe, serviceAccount, r.Scheme) + return nil + }) + if err != nil { + log.Error(err, "Error creating ServiceAccount", "ServiceAccount.Namespace", serviceAccount.Namespace, "ServiceAccount.Name", serviceAccount.Name) + return true, err + } + + log.Info("Successfully created ServiceAccount", "ServiceAccount.Namespace", serviceAccount.Namespace, "ServiceAccount.Name", serviceAccount.Name) + return false, nil +}