Create generated objects in runtime namespace
This uses the Downward API to inject the runtime namespace of the controller as an env var, rather than hard-coding it as 'vino-system'. It then uses the runtime namespace to lookup the default DaemonSet template, and then to co-locate the generated DaemonSet and bound ConfigMap with the controller, so that a static service account can be used by the DaemonSet, regardless of which namespace Vino CRs are created in. The names of the generated objects are now uniquely identified by the namespace/name of the Vino CR to avoid conflicts. Some other future use cases for the injected runtime namespace could include: - create ipam CRs in the same namespace as the controller - tenant namespacing, e.g. add a flag to limit the controller to only watch for Vino CRs in the runtime namespace Signed-off-by: Sean Eagan <seaneagan1@gmail.com> Change-Id: I47994782342c9c4ef749054017969386cefad3b8
This commit is contained in:
parent
817cbfc967
commit
1f360788c1
@ -37,4 +37,9 @@ spec:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 20Mi
|
||||
env:
|
||||
- name: RUNTIME_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
terminationGracePeriodSeconds: 10
|
||||
|
@ -19,6 +19,7 @@ package controllers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
@ -41,9 +42,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DaemonSetTemplateDefaultDataKey = "template"
|
||||
DaemonSetTemplateDefaultName = "vino-daemonset-template"
|
||||
DaemonSetTemplateDefaultNamespace = "vino-system"
|
||||
DaemonSetTemplateDefaultDataKey = "template"
|
||||
DaemonSetTemplateDefaultName = "vino-daemonset-template"
|
||||
|
||||
ContainerNameLibvirt = "libvirt"
|
||||
ConfigMapKeyVinoSpec = "vino-spec"
|
||||
@ -246,7 +246,7 @@ func (r *VinoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
|
||||
}
|
||||
}
|
||||
|
||||
err = r.reconcileConfigMap(ctx, req.NamespacedName, vino)
|
||||
err = r.reconcileConfigMap(ctx, vino)
|
||||
if err != nil {
|
||||
return ctrl.Result{Requeue: true}, err
|
||||
}
|
||||
@ -271,8 +271,8 @@ func (r *VinoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *VinoReconciler) reconcileConfigMap(ctx context.Context, name types.NamespacedName, vino *vinov1.Vino) error {
|
||||
err := r.ensureConfigMap(ctx, name, vino)
|
||||
func (r *VinoReconciler) reconcileConfigMap(ctx context.Context, vino *vinov1.Vino) error {
|
||||
err := r.ensureConfigMap(ctx, vino)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("could not reconcile ConfigMap: %w", err)
|
||||
apimeta.SetStatusCondition(&vino.Status.Conditions, metav1.Condition{
|
||||
@ -310,10 +310,10 @@ func (r *VinoReconciler) reconcileConfigMap(ctx context.Context, name types.Name
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *VinoReconciler) ensureConfigMap(ctx context.Context, name types.NamespacedName, vino *vinov1.Vino) error {
|
||||
func (r *VinoReconciler) ensureConfigMap(ctx context.Context, vino *vinov1.Vino) error {
|
||||
logger := logr.FromContext(ctx)
|
||||
|
||||
generatedCM, err := r.buildConfigMap(ctx, name, vino)
|
||||
generatedCM, err := r.buildConfigMap(ctx, vino)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -342,7 +342,7 @@ func (r *VinoReconciler) ensureConfigMap(ctx context.Context, name types.Namespa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *VinoReconciler) buildConfigMap(ctx context.Context, name types.NamespacedName, vino *vinov1.Vino) (
|
||||
func (r *VinoReconciler) buildConfigMap(ctx context.Context, vino *vinov1.Vino) (
|
||||
*corev1.ConfigMap, error) {
|
||||
logr.FromContext(ctx).Info("Generating new config map for vino object")
|
||||
|
||||
@ -353,8 +353,8 @@ func (r *VinoReconciler) buildConfigMap(ctx context.Context, name types.Namespac
|
||||
|
||||
return &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name.Name,
|
||||
Namespace: name.Namespace,
|
||||
Namespace: getRuntimeNamespace(),
|
||||
Name: r.getConfigMapName(vino),
|
||||
},
|
||||
Data: map[string]string{
|
||||
ConfigMapKeyVinoSpec: string(data),
|
||||
@ -362,6 +362,10 @@ func (r *VinoReconciler) buildConfigMap(ctx context.Context, name types.Namespac
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *VinoReconciler) getConfigMapName(vino *vinov1.Vino) string {
|
||||
return fmt.Sprintf("%s-%s", vino.Namespace, vino.Name)
|
||||
}
|
||||
|
||||
func (r *VinoReconciler) getCurrentConfigMap(ctx context.Context, vino *vinov1.Vino) (*corev1.ConfigMap, error) {
|
||||
logr.FromContext(ctx).Info("Getting current config map for vino object")
|
||||
cm := &corev1.ConfigMap{}
|
||||
@ -470,8 +474,8 @@ func (r *VinoReconciler) decorateDaemonSet(ctx context.Context, ds *appsv1.Daemo
|
||||
volume := "vino-spec"
|
||||
|
||||
ds.Spec.Template.Spec.NodeSelector = vino.Spec.NodeSelector.MatchLabels
|
||||
ds.Name = vino.Name
|
||||
ds.Namespace = vino.Namespace
|
||||
ds.Namespace = getRuntimeNamespace()
|
||||
ds.Name = fmt.Sprintf("%s-%s", vino.Namespace, vino.Name)
|
||||
|
||||
found := false
|
||||
for _, vol := range ds.Spec.Template.Spec.Volumes {
|
||||
@ -485,7 +489,7 @@ func (r *VinoReconciler) decorateDaemonSet(ctx context.Context, ds *appsv1.Daemo
|
||||
Name: volume,
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
ConfigMap: &corev1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: corev1.LocalObjectReference{Name: vino.Name},
|
||||
LocalObjectReference: corev1.LocalObjectReference{Name: r.getConfigMapName(vino)},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -593,7 +597,7 @@ func (r *VinoReconciler) daemonSet(ctx context.Context, vino *vinov1.Vino) (*app
|
||||
if dsTemplate == (vinov1.NamespacedName{}) {
|
||||
logger.Info("using default configmap for daemonset template")
|
||||
dsTemplate.Name = DaemonSetTemplateDefaultName
|
||||
dsTemplate.Namespace = DaemonSetTemplateDefaultNamespace
|
||||
dsTemplate.Namespace = getRuntimeNamespace()
|
||||
}
|
||||
|
||||
err := r.Get(ctx, types.NamespacedName{
|
||||
@ -766,3 +770,7 @@ func applyRuntimeObject(ctx context.Context, key client.ObjectKey, obj client.Ob
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func getRuntimeNamespace() string {
|
||||
return os.Getenv("RUNTIME_NAMESPACE")
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ if ! kubectl wait --for=condition=Ready vino vino-test-cr --timeout=180s; then
|
||||
fi
|
||||
|
||||
# no need to collect logs on fail, since they are already collected before
|
||||
until [[ $(kubectl get ds vino-test-cr 2>/dev/null) ]]; do
|
||||
until [[ $(kubectl -n vino-system get ds default-vino-test-cr 2>/dev/null) ]]; do
|
||||
count=$((count + 1))
|
||||
if [[ ${count} -eq "30" ]]; then
|
||||
echo ' Timed out waiting for vino builder daemonset to exist'
|
||||
@ -38,6 +38,6 @@ until [[ $(kubectl get ds vino-test-cr 2>/dev/null) ]]; do
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
if ! kubectl rollout status ds vino-test-cr --timeout=10s; then
|
||||
if ! kubectl -n vino-system rollout status ds default-vino-test-cr --timeout=10s; then
|
||||
vinoDebugInfo
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user