Skip to content

Commit

Permalink
Add status in account object
Browse files Browse the repository at this point in the history
Signed-off-by: Rokibul Hasan <[email protected]>
  • Loading branch information
RokibulHasan7 committed Aug 9, 2024
1 parent b1d297c commit e692bd1
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 19 deletions.
2 changes: 1 addition & 1 deletion pkg/agent/controller/managedclusterrole_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (r *ManagedClusterRoleReconciler) Reconcile(ctx context.Context, req ctrl.R

managedClusterRole := &authorizationv1alpha1.ManagedClusterRole{}
if err := r.HubClient.Get(ctx, req.NamespacedName, managedClusterRole); err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, client.IgnoreNotFound(err)
}

// create clusterRole in spoke cluster
Expand Down
7 changes: 3 additions & 4 deletions pkg/agent/controller/managedclusterrolebinding_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (

authzv1alpah1 "github.com/kluster-manager/cluster-auth/apis/authorization/v1alpha1"
"github.com/kluster-manager/cluster-auth/pkg/common"
"github.com/kluster-manager/cluster-auth/pkg/utils"

rbac "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -62,9 +61,9 @@ func (r *ManagedClusterRoleBindingReconciler) Reconcile(ctx context.Context, req

var managedCRB authzv1alpah1.ManagedClusterRoleBinding
if err := r.HubClient.Get(ctx, req.NamespacedName, &managedCRB); err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, client.IgnoreNotFound(err)
}
_, hubOwnerID := utils.GetUserIDAndHubOwnerIDFromLabelValues(&managedCRB)

userName := managedCRB.Subjects[0].Name

// Check if the managedCRB is marked for deletion
Expand All @@ -91,7 +90,7 @@ func (r *ManagedClusterRoleBindingReconciler) Reconcile(ctx context.Context, req
// impersonate clusterRole
cr := rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("impersonate-%s-%s-%s", userName, hubOwnerID, rand.String(7)),
Name: fmt.Sprintf("ace.%s.impersonate.%s", userName, rand.String(10)),
Labels: managedCRB.Labels,
},
Rules: []rbac.PolicyRule{
Expand Down
2 changes: 2 additions & 0 deletions pkg/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ const (
UserAuthLabel = "authentication.k8s.appscode.com/user"
HubOwnerLabel = "authentication.k8s.appscode.com/hub-owner"
HubClusterIdLabel = "cluster.k8s.appscode.com/cluster-id"

ServiceAccountPrefix = "system:serviceaccount:"
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ spec:
- name: agent
securityContext:
{{- toYaml .Values.image.securityContext | nindent 10 }}
{{/* image: {{ include "image.registry" . }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}*/}}
{{/* imagePullPolicy: {{ .Values.imagePullPolicy }}*/}}
image: rokibulhasan114/cluster-auth:version-update_linux_amd64
imagePullPolicy: Always
image: {{ include "image.registry" . }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
args:
- agent
- --v={{ .Values.logLevel }}
Expand Down
117 changes: 108 additions & 9 deletions pkg/manager/controller/authentication/account_controller.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
/*
Copyright AppsCode Inc. and Contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package authentication

import (
"context"
"fmt"
"strings"

authenticationv1alpha1 "github.com/kluster-manager/cluster-auth/apis/authentication/v1alpha1"
"github.com/kluster-manager/cluster-auth/pkg/common"

core "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
kmapi "kmodules.xyz/client-go/api/v1"
cu "kmodules.xyz/client-go/client"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
Expand All @@ -32,19 +50,34 @@ func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
acc := &authenticationv1alpha1.Account{}
err := r.Client.Get(ctx, req.NamespacedName, acc)
if err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, client.IgnoreNotFound(err)
}

// Update status to InProgress only if not already set
if acc.Status.Phase == "" {
acc.Status.Phase = authenticationv1alpha1.AccountPhaseInProgress
setAccountType(acc)
if err := r.Client.Status().Update(ctx, acc); err != nil {
return reconcile.Result{}, err
}
}
if err = r.createServiceAccount(ctx, acc); err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, r.setStatusFailed(ctx, acc, err)
}

if err = r.createGatewayClusterRoleBindingForUser(ctx, acc); err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, r.setStatusFailed(ctx, acc, err)
}

if err = r.createClusterRoleAndClusterRoleBindingToImpersonate(ctx, acc); err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, r.setStatusFailed(ctx, acc, err)
}

// Set the status to success after successful reconciliation
if acc.Status.Phase != authenticationv1alpha1.AccountPhaseCurrent {
if err := r.setStatusSuccess(ctx, acc, "Reconciliation completed successfully."); err != nil {
return reconcile.Result{}, err
}
}

return reconcile.Result{}, nil
Expand Down Expand Up @@ -104,7 +137,7 @@ func (r *AccountReconciler) createGatewayClusterRoleBindingForUser(ctx context.C
},
}

if acc.Spec.Type == authenticationv1alpha1.AccountTypeServiceAccount {
if strings.Contains(acc.Spec.Username, common.ServiceAccountPrefix) {
sub = []rbac.Subject{
{
APIGroup: "",
Expand All @@ -130,7 +163,7 @@ func (r *AccountReconciler) createGatewayClusterRoleBindingForUser(ctx context.C
},
}

if acc.Spec.Type == authenticationv1alpha1.AccountTypeServiceAccount {
if strings.Contains(acc.Spec.Username, common.ServiceAccountPrefix) {
crb.Name = fmt.Sprintf("ace.%s.proxy", acc.Spec.Username)
}

Expand Down Expand Up @@ -165,7 +198,7 @@ func (r *AccountReconciler) createClusterRoleAndClusterRoleBindingToImpersonate(
},
}

if acc.Spec.Type == authenticationv1alpha1.AccountTypeServiceAccount {
if strings.Contains(acc.Spec.Username, common.ServiceAccountPrefix) {
cr = rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("ace.%s.impersonate", acc.Spec.Username),
Expand Down Expand Up @@ -232,9 +265,75 @@ func (r *AccountReconciler) createClusterRoleAndClusterRoleBindingToImpersonate(
return nil
}

// updateConditions adds or updates a condition in the conditions array.
func (r *AccountReconciler) updateConditions(conditions []kmapi.Condition, conditionType kmapi.ConditionType, message string) []kmapi.Condition {
now := metav1.Now()
for i, condition := range conditions {
if condition.Type == conditionType {
conditions[i].Status = metav1.ConditionStatus(core.ConditionTrue)
conditions[i].LastTransitionTime = now
conditions[i].Message = message
return conditions
}
}

return append(conditions, kmapi.Condition{
Type: conditionType,
Status: metav1.ConditionStatus(core.ConditionTrue),
LastTransitionTime: now,
Reason: string(conditionType),
Message: message,
})
}

func (r *AccountReconciler) setStatusFailed(ctx context.Context, acc *authenticationv1alpha1.Account, err error) error {
// Re-fetch the latest version of the Account object
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(acc), acc); err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("failed to get latest account object: %w", err)
}

acc.Status.Phase = authenticationv1alpha1.AccountPhaseFailed
setAccountType(acc)

acc.Status.Conditions = r.updateConditions(acc.Status.Conditions, "ReconciliationFailed", err.Error())
if updateErr := r.Client.Status().Update(ctx, acc); updateErr != nil {
return fmt.Errorf("failed to update status to Failed: %w", updateErr)
}
return err
}

func (r *AccountReconciler) setStatusSuccess(ctx context.Context, acc *authenticationv1alpha1.Account, message string) error {
// Re-fetch the latest version of the Account object
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(acc), acc); err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("failed to get latest account object: %w", err)
}

acc.Status.Phase = authenticationv1alpha1.AccountPhaseCurrent
acc.Status.Conditions = r.updateConditions(acc.Status.Conditions, "ReconciliationSuccessful", message)
setAccountType(acc)
acc.Status.ServiceAccountRef = &core.LocalObjectReference{
Name: acc.Name,
}

// Update or add a successful condition
acc.Status.Conditions = r.updateConditions(acc.Status.Conditions, "ReconciliationSuccessful", message)
if updateErr := r.Client.Status().Update(ctx, acc); updateErr != nil {
return fmt.Errorf("failed to update status to Current: %w", updateErr)
}
return nil
}

func setAccountType(acc *authenticationv1alpha1.Account) {
if strings.Contains(acc.Spec.Username, common.ServiceAccountPrefix) {
acc.Status.Type = authenticationv1alpha1.AccountTypeServiceAccount
} else {
acc.Status.Type = authenticationv1alpha1.AccountTypeUser
}
}

// SetupWithManager sets up the controller with the Manager.
func (r *AccountReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&authenticationv1alpha1.Account{}).Watches(&authenticationv1alpha1.Account{}, &handler.EnqueueRequestForObject{}).
For(&authenticationv1alpha1.Account{}).
Complete(r)
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (r *ManagedClusterSetRoleBindingReconciler) Reconcile(ctx context.Context,
managedCSRB := &authorizationv1alpha1.ManagedClusterSetRoleBinding{}
err := r.Client.Get(ctx, req.NamespacedName, managedCSRB)
if err != nil {
return reconcile.Result{}, err
return reconcile.Result{}, client.IgnoreNotFound(err)
}

// Check if the managedCRB is marked for deletion
Expand Down

0 comments on commit e692bd1

Please sign in to comment.