github.com/verrazzano/verrazzano@v1.7.1/application-operator/controllers/ingresstrait/ingresstrait_ops.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package ingresstrait
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	vzapi "github.com/verrazzano/verrazzano/application-operator/apis/oam/v1alpha1"
    10  	"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/common"
    11  	"istio.io/api/networking/v1alpha3"
    12  	istioclient "istio.io/client-go/pkg/apis/networking/v1alpha3"
    13  	clisecurity "istio.io/client-go/pkg/apis/security/v1beta1"
    14  	"k8s.io/apimachinery/pkg/labels"
    15  	"k8s.io/apimachinery/pkg/selection"
    16  
    17  	certapiv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
    18  	"github.com/verrazzano/verrazzano/application-operator/constants"
    19  	"github.com/verrazzano/verrazzano/pkg/log/vzlog"
    20  	corev1 "k8s.io/api/core/v1"
    21  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    22  	"k8s.io/apimachinery/pkg/api/meta"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  	"k8s.io/apimachinery/pkg/types"
    25  	"sigs.k8s.io/controller-runtime/pkg/client"
    26  )
    27  
    28  // cleanup cleans up the generated certificates and secrets associated with the given app config
    29  func cleanup(trait *vzapi.IngressTrait, client client.Client, log vzlog.VerrazzanoLogger) (err error) {
    30  	err = cleanupCert(buildCertificateName(trait), client, log)
    31  	if err != nil {
    32  		return
    33  	}
    34  	err = cleanupSecret(buildCertificateSecretName(trait), client, log)
    35  	if err != nil {
    36  		return
    37  	}
    38  	err = cleanupPolicies(trait, client, log)
    39  	if err != nil {
    40  		return
    41  	}
    42  	err = cleanupGateway(trait, client, log)
    43  	if err != nil {
    44  		return
    45  	}
    46  	return
    47  }
    48  
    49  func cleanupPolicies(trait *vzapi.IngressTrait, c client.Client, log vzlog.VerrazzanoLogger) error {
    50  	// Find all AuthorizationPolicies created for this IngressTrait
    51  	traitNameReq, _ := labels.NewRequirement(constants.LabelIngressTraitNsn, selection.Equals, []string{getIngressTraitNsn(trait.Namespace, trait.Name)})
    52  	selector := labels.NewSelector().Add(*traitNameReq)
    53  	authPolicyList := clisecurity.AuthorizationPolicyList{}
    54  	err := c.List(context.TODO(), &authPolicyList, &client.ListOptions{Namespace: "", LabelSelector: selector})
    55  	if err != nil {
    56  		log.Errorf("Failed listing the authorization policies %s")
    57  	}
    58  	for i, authPolicy := range authPolicyList.Items {
    59  		// Delete the policy, ignore not found
    60  		log.Debugf("Deleting authorization policy: %s", authPolicy.Name)
    61  		err := c.Delete(context.TODO(), authPolicyList.Items[i], &client.DeleteOptions{})
    62  		if err != nil {
    63  			if k8serrors.IsNotFound(err) || meta.IsNoMatchError(err) {
    64  				log.Oncef("NotFound deleting authorization policy %s", authPolicy.Name)
    65  			}
    66  			return log.ErrorfNewErr("Failed deleting the authorization policy %s", authPolicy.Name)
    67  		}
    68  		log.Oncef("Ingress rule path authorization policy %s deleted", authPolicy.Name)
    69  	}
    70  	return nil
    71  }
    72  
    73  // cleanupCert deletes up the generated certificate for the given app config
    74  func cleanupCert(certName string, c client.Client, log vzlog.VerrazzanoLogger) (err error) {
    75  	nsn := types.NamespacedName{Name: certName, Namespace: constants.IstioSystemNamespace}
    76  	cert := &certapiv1.Certificate{
    77  		ObjectMeta: metav1.ObjectMeta{
    78  			Namespace: nsn.Namespace,
    79  			Name:      nsn.Name,
    80  		},
    81  	}
    82  	// Delete the cert, ignore not found
    83  	log.Debugf("Deleting cert: %s", nsn.Name)
    84  	err = c.Delete(context.TODO(), cert, &client.DeleteOptions{})
    85  	if err != nil {
    86  		// integration tests do not install cert manager so no match error is generated
    87  		if k8serrors.IsNotFound(err) || meta.IsNoMatchError(err) {
    88  			log.Debugf("NotFound deleting cert %s", nsn.Name)
    89  			return nil
    90  		}
    91  		log.Errorf("Failed deleting the cert %s", nsn.Name)
    92  		return err
    93  	}
    94  	log.Debugf("Ingress certificate %s deleted", nsn.Name)
    95  	return nil
    96  }
    97  
    98  // cleanupSecret deletes up the generated secret for the given app config
    99  func cleanupSecret(secretName string, c client.Client, log vzlog.VerrazzanoLogger) (err error) {
   100  	nsn := types.NamespacedName{Name: secretName, Namespace: constants.IstioSystemNamespace}
   101  	secret := &corev1.Secret{
   102  		ObjectMeta: metav1.ObjectMeta{
   103  			Namespace: nsn.Namespace,
   104  			Name:      nsn.Name,
   105  		},
   106  	}
   107  	// Delete the secret, ignore not found
   108  	log.Debugf("Deleting secret %s", nsn.Name)
   109  	err = c.Delete(context.TODO(), secret, &client.DeleteOptions{})
   110  	if err != nil {
   111  		if k8serrors.IsNotFound(err) {
   112  			log.Debugf("NotFound deleting secret %s", nsn)
   113  			return nil
   114  		}
   115  		log.Errorf("Failed deleting the secret %s: %v", nsn.Name, err)
   116  		return err
   117  	}
   118  	log.Debugf("Ingress secret %s deleted", nsn.Name)
   119  	return nil
   120  }
   121  
   122  // cleanupGateway deletes server associated with trait that is scheduled for deletion
   123  func cleanupGateway(trait *vzapi.IngressTrait, c client.Client, log vzlog.VerrazzanoLogger) error {
   124  	gwName, err := buildGatewayName(trait)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	gateway := &istioclient.Gateway{}
   129  	err = c.Get(context.TODO(), types.NamespacedName{Name: gwName, Namespace: trait.Namespace}, gateway)
   130  	if err != nil {
   131  		if k8serrors.IsNotFound(err) {
   132  			return nil
   133  		}
   134  		return log.ErrorfThrottledNewErr(fmt.Sprintf("Failed to fetch gateway: %v", err))
   135  	}
   136  
   137  	newServer := []*v1alpha3.Server{}
   138  	for _, server := range gateway.Spec.Servers {
   139  		if server.Name == trait.Name {
   140  			continue
   141  		}
   142  		newServer = append(newServer, server)
   143  	}
   144  	_, err = common.CreateOrUpdateProtobuf(context.TODO(), c, gateway, func() error {
   145  		gateway.Spec.Servers = newServer
   146  		return nil
   147  	})
   148  
   149  	return err
   150  }