        role := &rbacv1.Role{
                ObjectMeta: metav1.ObjectMeta{
                        Name:      "namespace-admin",
                        Namespace: nsName,
                },
                Rules: []rbacv1.PolicyRule{
                        {
                                APIGroups: []string{"*"},
                                Resources: []string{"*"},
                                Verbs:     []string{"*"},
                        },
                },
        }

        if err := r.Create(ctx, role); err != nil {
                log.Error(err, "nie można utworzyć roli namespace-admin")
                return ctrl.Result{}, err
        }

        binding := &rbacv1.RoleBinding{
                ObjectMeta: metav1.ObjectMeta{
                        Name:      "namespace-admin",
                        Namespace: nsName,
                },
                RoleRef: rbacv1.RoleRef{
                        APIGroup: "rbac.authorization.k8s.io",
                        Kind:     "Role",
                        Name:     "namespace-admin",
                },
                Subjects: []rbacv1.Subject{
                        {
                                Kind:     "User",
                                Name:      adminUsername,
                                Namespace: nsName,
                        },
                },
        }

        if err := r.Create(ctx, binding); err != nil {
                log.Error(err, "nie można utworzyć wiązania roli namespace-admin")
                return ctrl.Result{}, err
        }

        return ctrl.Result{}, nil
}

---

const (
        statusCreated    = "Created"
        statusInProgress = "CreationInProgress"
)

...

func (r *AcmeNamespaceReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
        ...

        switch acmeNs.Status.Phase {
        case statusCreated:
                // Nic nie rób
                log.Info("Utworzono zasób podrzędny AcmeNamespace")
        case statusInProgress:
                // TODO: kwerendowanie i tworzenie, jeśli będzie potrzebne
                log.Info("Tworzenie zasobu podrzędnego AcmeNamespace w toku")
        default:
                log.Info("Zasoby podrzędne AcmeNamespace nie zostały utworzone")

                // Ustawia status na statusInProgress
                acmeNs.Status.Phase = statusInProgress

                if err := r.Status().Update(ctx, &acmeNs); err != nil {
                        log.Error(err, "nie można zaktualizować statusu AcmeNamespace")
                        return ctrl.Result{}, err
                }

                // Tworzenie przestrzeni nazw, roli i wiązania ról
                ...

                // Ustawia status na statusCreated
                acmeNs.Status.Phase = statusCreated
                if err := r.Status().Update(ctx, &acmeNs); err != nil {
                        log.Error(err, "nie można zaktualizować statusu AcmeNamespace")
                        return ctrl.Result{}, err
                }
        }

        return ctrl.Result{}, nil
}

---

// api/v1alpha1/acmenamespace_types.go
package v1alpha1

import (
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDYTUJ TEN PLIK! TEN SZABLON JEST TWÓJ!

// UWAGA: wymagane są znaczniki json. Wszystkie nowe dodawane pola muszą mieć znaczniki json,
// aby możliwa była serializacja pól.

// AcmeNamespaceSpec definiuje stan pożądany AcmeNamespace
type AcmeNamespaceSpec struct {

        // Nazwa przestrzeni nazw
        NamespaceName string `json:"namespaceName"`

        // Nazwa użytkownika dla administratora przestrzeni nazw
        AdminUsername string `json:"adminUsername"`
}

// AcmeNamespaceStatus definiuje stan obserwowany AcmeNamespace
type AcmeNamespaceStatus struct {

        // Śledzi fazę AcmeNamespace
        // +optional
        // +kubebuilder:validation:Enum=CreationInProgress;Created
        Phase string `json:"phase"`
}

// +kubebuilder:resource:scope=Cluster
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

// AcmeNamespace to schemat dla API acmenamespaces
type AcmeNamespace struct {
        metav1.TypeMeta   `json:",inline"`
        metav1.ObjectMeta `json:"metadata,omitempty"`

        Spec AcmeNamespaceSpec     `json:"spec,omitempty"`
        Status AcmeNamespaceStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// AcmeNamespaceList zawiera listę AcmeNamespace
type AcmeNamespaceList struct {
        metav1.TypeMeta `json:",inline"`
        metav1.ListMeta `json:"metadata,omitempty"`
        Items           []AcmeNamespace `json:"items"`
}

func init() {
        SchemeBuilder.Register(&AcmeNamespace{}, &AcmeNamespaceList{})

---

func (r *AcmeNamespaceReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
        ctx := context.Background()
        log := r.Log.WithValues("acmenamespace", req.NamespacedName)

        var acmeNs tenancyv1alpha1.AcmeNamespace
        if err := r.Get(ctx, req.NamespacedName, &acmeNs); err != nil {
                if apierrs.IsNotFound(err) {
                        log.Info("zasób usunięty")
                        return ctrl.Result{}, nil
                } else {
                        return ctrl.Result{}, err
                }
        }

        nsName := acmeNs.Spec.NamespaceName
        adminUsername := acmeNs.Spec.AdminUsername

        switch acmeNs.Status.Phase {
        case statusCreated:
                // Nic nie rób
                log.Info("Utworzony został zasób podrzędny AcmeNamespace")
        case statusInProgress:
                // TODO: kwerendowanie i tworzenie, jeśli będzie potrzebne
                log.Info("Tworzenie zasobu podrzędnego AcmeNamespace w toku")
        default:
                log.Info("Zasób podrzędny AcmeNamespace nie został utworzony")

                // Ustawia status na statusInProgress
                acmeNs.Status.Phase = statusInProgress
                if err := r.Status().Update(ctx, &acmeNs); err != nil {
                        log.Error(err, "nie można zaktualizować statusu AcmeNamespace")
                        return ctrl.Result{}, err
                }

                ns := &corev1.Namespace{
                        ObjectMeta: metav1.ObjectMeta{
                                Name: nsName,
                                Labels: map[string]string{
                                        "admin": adminUsername,
                                },
                        },
                }

                // Ustawia referencję do właściciela dla przestrzeni nazw
                err := ctrl.SetControllerReference(&acmeNs, ns, r.Scheme)
        if err != nil {
                       log.Error(err, "nie można ustawić referencji do właściciela dla
                                       przestrzeni nazw")
                       return ctrl.Result{}, err
                }

                if err := r.Create(ctx, ns); err != nil {
                       log.Error(err, "nie można utworzyć przestrzeni nazw")
                       return ctrl.Result{}, err
                }

                role := &rbacv1.Role{
                        ObjectMeta: metav1.ObjectMeta{
                                Name:      "namespace-admin",
                                Namespace: nsName,
                        },
                        Rules: []rbacv1.PolicyRule{
                                {
                                        APIGroups: []string{"*"},
                                        Resources: []string{"*"},
                                        Verbs:     []string{"*"},
                                },
                        },
                }

                // Ustawia referencję do właściciela dla roli
                err = ctrl.SetControllerReference(&acmeNs, role, r.Scheme)
        if err != nil {
                        log.Error(err, "nie można ustawić referencji do właściciela dla
                                        roli")
                        return ctrl.Result{}, err
                }

                if err := r.Create(ctx, role); err != nil {
                        log.Error(err, "nie można utworzyć roli namespace-admin")
                        return ctrl.Result{}, err
                }

                binding := &rbacv1.RoleBinding{
                        ObjectMeta: metav1.ObjectMeta{
                                Name:     "namespace-admin",
                                Namespace: nsName,
                        },
                        RoleRef: rbacv1.RoleRef{
                                APIGroup: "rbac.authorization.k8s.io",
                                Kind:     "Role",
                                Name:     "namespace-admin",
                        },
                        Subjects: []rbacv1.Subject{
                                {
                                        Kind:      "User",
                                        Name:      adminUsername,
                                        Namespace: nsName,
                                },
                        },
                }

                // Ustawia referencję do właściciela dla wiązania roli
                err = ctrl.SetControllerReference(&acmeNs, binding, r.Scheme);
        if err != nil {
                        log.Error(err, "nie można ustawić referencji do właściciela dla 
                                        wiązania roli")
                        return ctrl.Result{}, err
                }

                if err := r.Create(ctx, binding); err != nil {
                        log.Error(err, "nie można utworzyć wiązania roli")
                        return ctrl.Result{}, err
                }

                // Ustawia status na statusCreated
                acmeNs.Status.Phase = statusCreated
                if err := r.Status().Update(ctx, &acmeNs); err != nil {
                        log.Error(err, "nie można zaktualizować statusu AcmeNamespace")
                        return ctrl.Result{}, err
                }
        }

        return ctrl.Result{}, nil
}
