Skip to content

Commit

Permalink
code-refactoring: port mappers; finish argocd_controller helper funct…
Browse files Browse the repository at this point in the history
…ions (argoproj-labs#1289)

* port mappers; finish argocd_controller helper fns

---------

Signed-off-by: Jaideep Rao <[email protected]>
  • Loading branch information
jaideepr97 authored Mar 28, 2024
1 parent 3143bd9 commit 970ee78
Show file tree
Hide file tree
Showing 12 changed files with 539 additions and 284 deletions.
4 changes: 2 additions & 2 deletions common/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOf
)

// DefaultLabels returns the default set of labels for controllers.
func DefaultResourceLabels(resourceName, instanceName, component string) map[string]string {
func DefaultResourceLabels(resourceName, instanceNamespace, component string) map[string]string {
LabelsMap := map[string]string{
AppK8sKeyName: resourceName,
AppK8sKeyPartOf: ArgoCDAppName,
AppK8sKeyInstance: instanceName,
AppK8sKeyInstance: instanceNamespace,
AppK8sKeyManagedBy: ArgoCDOperatorName,
}

Expand Down
2 changes: 2 additions & 0 deletions common/envVars.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ const (
ArgoCDOperatorLogLevelEnvVar = "LOG_LEVEL"

ArgoCDReconciliationTImeOutEnvVar = "ARGOCD_RECONCILIATION_TIMEOUT"

ArgoCDRemoveManagedByLabelOnDeletionEnvVar = "REMOVE_MANAGED_BY_LABEL_ON_ARGOCD_DELETION"
)
3 changes: 2 additions & 1 deletion common/reposerver.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const (

// suffixes
const (
RepoServerSuffix = "repo-server"
RepoServerSuffix = "repo-server"
RepoServerTLSSuffix = "repo-server-tls"
)

// values
Expand Down
216 changes: 216 additions & 0 deletions controllers/argocd/TOBEREMOVED.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -1337,3 +1338,218 @@ func (r *ReconcileArgoCD) reconcileCertificateAuthority(cr *argoproj.ArgoCD) err
}
return nil
}

func (r *ReconcileArgoCD) clusterResourceMapper(ctx context.Context, o client.Object) []reconcile.Request {
crbAnnotations := o.GetAnnotations()
namespacedArgoCDObject := client.ObjectKey{}

for k, v := range crbAnnotations {
if k == common.AnnotationName {
namespacedArgoCDObject.Name = v
} else if k == common.AnnotationNamespace {
namespacedArgoCDObject.Namespace = v
}
}

var result = []reconcile.Request{}
if namespacedArgoCDObject.Name != "" && namespacedArgoCDObject.Namespace != "" {
result = []reconcile.Request{
{NamespacedName: namespacedArgoCDObject},
}
}
return result
}

// tlsSecretMapper maps a watch event on a secret of type TLS back to the
// ArgoCD object that we want to reconcile.
func (r *ReconcileArgoCD) tlsSecretMapper(ctx context.Context, o client.Object) []reconcile.Request {
var result = []reconcile.Request{}

if !isSecretOfInterest(o) {
return result
}
namespacedArgoCDObject := client.ObjectKey{}

secretOwnerRefs := o.GetOwnerReferences()
if len(secretOwnerRefs) > 0 {
// OpenShift service CA makes the owner reference for the TLS secret to the
// service, which in turn is owned by the controller. This method performs
// a lookup of the controller through the intermediate owning service.
for _, secretOwner := range secretOwnerRefs {
if isOwnerOfInterest(secretOwner) {
key := client.ObjectKey{Name: secretOwner.Name, Namespace: o.GetNamespace()}
svc := &corev1.Service{}

// Get the owning object of the secret
err := r.Client.Get(context.TODO(), key, svc)
if err != nil {
log.Error(err, fmt.Sprintf("could not get owner of secret %s", o.GetName()))
return result
}

// If there's an object of kind ArgoCD in the owner's list,
// this will be our reconciled object.
serviceOwnerRefs := svc.GetOwnerReferences()
for _, serviceOwner := range serviceOwnerRefs {
if serviceOwner.Kind == "ArgoCD" {
namespacedArgoCDObject.Name = serviceOwner.Name
namespacedArgoCDObject.Namespace = svc.ObjectMeta.Namespace
result = []reconcile.Request{
{NamespacedName: namespacedArgoCDObject},
}
return result
}
}
}
}
} else {
// For secrets without owner (i.e. manually created), we apply some
// heuristics. This may not be as accurate (e.g. if the user made a
// typo in the resource's name), but should be good enough for now.
secret, ok := o.(*corev1.Secret)
if !ok {
return result
}
if owner, ok := secret.Annotations[common.AnnotationName]; ok {
namespacedArgoCDObject.Name = owner
namespacedArgoCDObject.Namespace = o.GetNamespace()
result = []reconcile.Request{
{NamespacedName: namespacedArgoCDObject},
}
}
}

return result
}

// clusterSecretResourceMapper maps a watch event on a namespace, back to the
// ArgoCD object that we want to reconcile.
func (r *ReconcileArgoCD) clusterSecretResourceMapper(ctx context.Context, o client.Object) []reconcile.Request {
var result = []reconcile.Request{}

labels := o.GetLabels()
if v, ok := labels[common.ArgoCDSecretTypeLabel]; ok && v == "cluster" {
argocds := &argoproj.ArgoCDList{}
if err := r.Client.List(context.TODO(), argocds, &client.ListOptions{Namespace: o.GetNamespace()}); err != nil {
return result
}

if len(argocds.Items) != 1 {
return result
}

argocd := argocds.Items[0]
namespacedName := client.ObjectKey{
Name: argocd.Name,
Namespace: argocd.Namespace,
}
result = []reconcile.Request{
{NamespacedName: namespacedName},
}
}

return result
}

// applicationSetSCMTLSConfigMapMapper maps a watch event on a configmap with name "argocd-appset-gitlab-scm-tls-certs-cm",
// back to the ArgoCD object that we want to reconcile.
func (r *ReconcileArgoCD) applicationSetSCMTLSConfigMapMapper(ctx context.Context, o client.Object) []reconcile.Request {
var result = []reconcile.Request{}

if o.GetName() == common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName {
argocds := &argoproj.ArgoCDList{}
if err := r.Client.List(context.TODO(), argocds, &client.ListOptions{Namespace: o.GetNamespace()}); err != nil {
return result
}

if len(argocds.Items) != 1 {
return result
}

argocd := argocds.Items[0]
namespacedName := client.ObjectKey{
Name: argocd.Name,
Namespace: argocd.Namespace,
}
result = []reconcile.Request{
{NamespacedName: namespacedName},
}
}

return result
}

func (r *ReconcileArgoCD) deleteClusterResources(cr *argoproj.ArgoCD) error {
selector, err := argocdInstanceSelector(cr.Name)
if err != nil {
return err
}

clusterRoleList := &v1.ClusterRoleList{}
if err := filterObjectsBySelector(r.Client, clusterRoleList, selector); err != nil {
return fmt.Errorf("failed to filter ClusterRoles for %s: %w", cr.Name, err)
}

if err := deleteClusterRoles(r.Client, clusterRoleList); err != nil {
return err
}

clusterBindingsList := &v1.ClusterRoleBindingList{}
if err := filterObjectsBySelector(r.Client, clusterBindingsList, selector); err != nil {
return fmt.Errorf("failed to filter ClusterRoleBindings for %s: %w", cr.Name, err)
}

if err := deleteClusterRoleBindings(r.Client, clusterBindingsList); err != nil {
return err
}

return nil
}

func (r *ReconcileArgoCD) removeManagedByLabelFromNamespaces(namespace string) error {
nsList := &corev1.NamespaceList{}
listOption := client.MatchingLabels{
common.ArgoCDManagedByLabel: namespace,
}
if err := r.Client.List(context.TODO(), nsList, listOption); err != nil {
return err
}

nsList.Items = append(nsList.Items, corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}})
for _, n := range nsList.Items {
ns := &corev1.Namespace{}
if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: n.Name}, ns); err != nil {
return err
}

if ns.Labels == nil {
continue
}

if n, ok := ns.Labels[common.ArgoCDManagedByLabel]; !ok || n != namespace {
continue
}
delete(ns.Labels, common.ArgoCDManagedByLabel)
if err := r.Client.Update(context.TODO(), ns); err != nil {
log.Error(err, fmt.Sprintf("failed to remove label from namespace [%s]", ns.Name))
}
}
return nil
}

func argocdInstanceSelector(name string) (labels.Selector, error) {
selector := labels.NewSelector()
requirement, err := labels.NewRequirement(common.ArgoCDKeyManagedBy, selection.Equals, []string{name})
if err != nil {
return nil, fmt.Errorf("failed to create a requirement for %w", err)
}
return selector.Add(*requirement), nil
}

func (r *ReconcileArgoCD) removeDeletionFinalizer(argocd *argoproj.ArgoCD) error {
argocd.Finalizers = removeString(argocd.GetFinalizers(), common.ArgoCDDeletionFinalizer)
if err := r.Client.Update(context.TODO(), argocd); err != nil {
return fmt.Errorf("failed to remove deletion finalizer from %s: %w", argocd.Name, err)
}
return nil
}
Loading

0 comments on commit 970ee78

Please sign in to comment.