@ -22,8 +22,11 @@ import (
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						"github.com/manifoldco/promptui" 
 
					 
					 
					 
						"github.com/manifoldco/promptui" 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						"github.com/spf13/cobra" 
 
					 
					 
					 
						"github.com/spf13/cobra" 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						apierrors  "k8s.io/apimachinery/pkg/api/errors" 
 
					 
					 
					 
						appsv1  "k8s.io/api/apps/v1" 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						"k8s.io/apimachinery/pkg/types" 
 
					 
					 
					 
						corev1  "k8s.io/api/core/v1" 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						rbacv1  "k8s.io/api/rbac/v1" 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						apiextensionsv1  "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						metav1  "k8s.io/apimachinery/pkg/apis/meta/v1" 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						"sigs.k8s.io/controller-runtime/pkg/client" 
 
					 
					 
					 
						"sigs.k8s.io/controller-runtime/pkg/client" 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						"github.com/fluxcd/flux2/internal/utils" 
 
					 
					 
					 
						"github.com/fluxcd/flux2/internal/utils" 
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -34,33 +37,27 @@ import (
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					var  uninstallCmd  =  & cobra . Command { 
 
					 
					 
					 
					var  uninstallCmd  =  & cobra . Command { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						Use :    "uninstall" , 
 
					 
					 
					 
						Use :    "uninstall" , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						Short :  "Uninstall  the toolkit component s", 
 
					 
					 
					 
						Short :  "Uninstall  Flux and its custom resource definition s", 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						Long :   "The uninstall command removes the  namespace, cluster roles, cluster role bindings and CRD s from the cluster.", 
 
					 
					 
					 
						Long :   "The uninstall command removes the  Flux components and the toolkit.fluxcd.io resource s from the cluster.", 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						Example :  `   #  Dry- run  uninstall  of  all  components  
 
					 
					 
					 
						Example :  `   #  Uninstall Flux  components ,  its  custom  resources  and  namespace  
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  flux  uninstall  -- dry- run  --  namespace= flux - system 
 
					 
					 
					 
					  flux  uninstall  --  namespace= flux - system 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  #  Uninstall  all components  and  delete  custom  resource  definitions  
 
					 
					 
					 
					  #  Uninstall  Flux but  keep  the  namespace  
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					  flux  uninstall  -- resources -- crds  -- namespace = flux - system  
 
					 
					 
					 
					  flux  uninstall  -- namespace= infra  -- keep - namespace = true  
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					` , 
 
					 
					 
					 
					` , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						RunE :  uninstallCmdRun , 
 
					 
					 
					 
						RunE :  uninstallCmdRun , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					type  uninstallFlags  struct  { 
 
					 
					 
					 
					type  uninstallFlags  struct  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						crds       bool 
 
					 
					 
					 
						keepNamespace  bool 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						resources  bool 
 
					 
					 
					 
						silent         bool 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						dryRun     bool 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						silent     bool 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					var  uninstallArgs  uninstallFlags 
 
					 
					 
					 
					var  uninstallArgs  uninstallFlags 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					func  init ( )  { 
 
					 
					 
					 
					func  init ( )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						uninstallCmd . Flags ( ) . BoolVar ( & uninstallArgs . resources ,  "resources" ,  true , 
 
					 
					 
					 
						uninstallCmd . Flags ( ) . BoolVar ( & uninstallArgs . keepNamespace ,  "keep-namespace" ,  false , 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							"removes custom resources such as Kustomizations, GitRepositories and HelmRepositories" ) 
 
					 
					 
					 
							"skip namespace deletion" ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						uninstallCmd . Flags ( ) . BoolVar ( & uninstallArgs . crds ,  "crds" ,  false , 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							"removes all CRDs previously installed" ) 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						uninstallCmd . Flags ( ) . BoolVar ( & uninstallArgs . dryRun ,  "dry-run" ,  false , 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							"only print the object that would be deleted" ) 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
						uninstallCmd . Flags ( ) . BoolVarP ( & uninstallArgs . silent ,  "silent" ,  "s" ,  false , 
 
					 
					 
					 
						uninstallCmd . Flags ( ) . BoolVarP ( & uninstallArgs . silent ,  "silent" ,  "s" ,  false , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							"delete components without asking for confirmation" ) 
 
					 
					 
					 
							"delete components without asking for confirmation" ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -68,6 +65,16 @@ func init() {
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					func  uninstallCmdRun ( cmd  * cobra . Command ,  args  [ ] string )  error  { 
 
					 
					 
					 
					func  uninstallCmdRun ( cmd  * cobra . Command ,  args  [ ] string )  error  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						if  ! uninstallArgs . silent  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							prompt  :=  promptui . Prompt { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								Label :      "Are you sure you want to delete Flux and its custom resource definitions" , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								IsConfirm :  true , 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  _ ,  err  :=  prompt . Run ( ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								return  fmt . Errorf ( "aborting" ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						ctx ,  cancel  :=  context . WithTimeout ( context . Background ( ) ,  rootArgs . timeout ) 
 
					 
					 
					 
						ctx ,  cancel  :=  context . WithTimeout ( context . Background ( ) ,  rootArgs . timeout ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						defer  cancel ( ) 
 
					 
					 
					 
						defer  cancel ( ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -76,96 +83,189 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							return  err 
 
					 
					 
					 
							return  err 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						if  ! uninstallArgs . dryRun  &&  ! uninstallArgs . silent  { 
 
					 
					 
					 
						logger . Actionf ( "deleting components in %s namespace" ,  rootArgs . namespace ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							prompt  :=  promptui . Prompt { 
 
					 
					 
					 
						uninstallComponents ( ctx ,  kubeClient ,  rootArgs . namespace ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								Label :      fmt . Sprintf ( "Are you sure you want to delete the %s namespace" ,  rootArgs . namespace ) , 
 
					 
					 
					 
					
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								IsConfirm :  true , 
 
					 
					 
					 
						logger . Actionf ( "deleting toolkit.fluxcd.io finalizers in all namespaces" ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
						uninstallFinalizers ( ctx ,  kubeClient ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							if  _ ,  err  :=  prompt . Run ( ) ;  err  !=  nil  { 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
								return  fmt . Errorf ( "aborting" ) 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						dryRun :=  "--dry-run=server"  
 
					 
					 
					 
						logger . Actionf ( "deleting toolkit.fluxcd.io custom resource definitions" ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						deleteResources  :=  uninstallArgs . resources  ||  uninstallArgs . crds 
 
					 
					 
					 
						uninstallCustomResourceDefinitions ( ctx ,  kubeClient ,  rootArgs . namespace ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						// known kinds with finalizers
 
 
					 
					 
					 
						if  ! uninstallArgs . keepNamespace  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						namespacedKinds  :=  [ ] string { 
 
					 
					 
					 
							uninstallNamespace ( ctx ,  kubeClient ,  rootArgs . namespace ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							sourcev1 . GitRepositoryKind , 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							sourcev1 . HelmRepositoryKind , 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							sourcev1 . BucketKind , 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						// suspend bootstrap kustomization to avoid finalizers deadlock
 
 
					 
					 
					 
						logger . Successf ( "uninstall finished" ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						kustomizationName  :=  types . NamespacedName { 
 
					 
					 
					 
						return  nil 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							Namespace :  rootArgs . namespace , 
 
					 
					 
					 
					} 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							Name :       rootArgs . namespace , 
 
					 
					 
					 
					
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					func  uninstallComponents ( ctx  context . Context ,  kubeClient  client . Client ,  namespace  string )  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						selector  :=  client . MatchingLabels { "app.kubernetes.io/instance" :  namespace } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						{ 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							var  list  appsv1 . DeploymentList 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( namespace ) ,  selector ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Delete ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "Deployment/%s/%s deletion failed: %s" ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "Deployment/%s/%s deleted" ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						var  kustomization  kustomizev1 . Kustomization 
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						err  =  kubeClient . Get ( ctx ,  kustomizationName ,  & kustomization ) 
 
					 
					 
					 
							var  list  corev1 . ServiceList 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						if  err  ==  nil  { 
 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( namespace ) ,  selector ) ;  err  ==  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							kustomization . Spec . Suspend  =  true 
 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							if  err  :=  kubeClient . Update ( ctx ,  & kustomization ) ;  err  !=  nil  { 
 
					 
					 
					 
									if  err  :=  kubeClient . Delete ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								return  fmt . Errorf ( "unable to suspend kustomization '%s': %w" ,  kustomizationName . String ( ) ,  err ) 
 
					 
					 
					 
										logger . Failuref ( "Service/%s/%s deletion failed: %s" ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "Service/%s/%s deleted" ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						if  err  ==  nil  ||  apierrors . IsNotFound ( err )  { 
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							namespacedKinds  =  append ( namespacedKinds ,  kustomizev1 . KustomizationKind ) 
 
					 
					 
					 
							var  list  corev1 . ServiceAccountList 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( namespace ) ,  selector ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Delete ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "ServiceAccount/%s/%s deletion failed: %s" ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "ServiceAccount/%s/%s deleted" ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						// add HelmRelease kind to deletion list if exists
 
 
					 
					 
					 
							var  list  rbacv1 . ClusterRoleList 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						var  list  helmv2 . HelmReleaseList 
 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  selector ) ;  err  ==  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( rootArgs . namespace ) ) ;  err  ==  nil  { 
 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							namespacedKinds  =  append ( namespacedKinds ,  helmv2 . HelmReleaseKind ) 
 
					 
					 
					 
									if  err  :=  kubeClient . Delete ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "ClusterRole/%s deletion failed: %s" ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "ClusterRole/%s deleted" ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						if  deleteResources  { 
 
					 
					 
					 
							var  list  rbacv1 . ClusterRoleBindingList 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							logger . Actionf ( "uninstalling custom resources" ) 
 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  selector ) ;  err  ==  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							for  _ ,  kind  :=  range  namespacedKinds  { 
 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								if  err  :=  deleteAll ( ctx ,  kind ,  uninstallArgs . dryRun ) ;  err  !=  nil  { 
 
					 
					 
					 
									if  err  :=  kubeClient . Delete ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
									logger . Failuref ( "kubectl: %s" ,  err . Error ( ) ) 
 
					 
					 
					 
										logger . Failuref ( "ClusterRoleBinding/%s deletion failed: %s" ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "ClusterRoleBinding/%s deleted" ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
								} 
 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						var  kinds  [ ] string 
 
					 
					 
					 
					func  uninstallFinalizers ( ctx  context . Context ,  kubeClient  client . Client )  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						if  uninstallArgs . crds  { 
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							kinds  =  append ( kinds ,  "crds" ) 
 
					 
					 
					 
							var  list  sourcev1 . GitRepositoryList 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( "" ) ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									r . Finalizers  =  [ ] string { } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Update ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "%s/%s/%s removing finalizers failed: %s" ,  r . Kind ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "%s/%s/%s finalizers deleted" ,  r . Kind ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						kinds  =  append ( kinds ,  "clusterroles,clusterrolebindings" ,  "namespace" ) 
 
					 
					 
					 
							var  list  sourcev1 . HelmRepositoryList 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( "" ) ) ;  err  ==  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						logger . Actionf ( "uninstalling components" ) 
 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
									r . Finalizers  =  [ ] string { } 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						for  _ ,  kind  :=  range  kinds  { 
 
					 
					 
					 
									if  err  :=  kubeClient . Update ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							kubectlArgs  :=  [ ] string { 
 
					 
					 
					 
										logger . Failuref ( "%s/%s/%s removing finalizers failed: %s" ,  r . Kind ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								"delete" ,  kind , 
 
					 
					 
					 
									}  else  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								"-l" ,  fmt . Sprintf ( "app.kubernetes.io/instance=%s" ,  rootArgs . namespace ) , 
 
					 
					 
					 
										logger . Successf ( "%s/%s/%s finalizers deleted" ,  r . Kind ,  r . Namespace ,  r . Name ) 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								"--ignore-not-found" ,  "--timeout" ,  rootArgs . timeout . String ( ) , 
 
					 
					 
					 
									} 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						{ 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							var  list  sourcev1 . HelmChartList 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( "" ) ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									r . Finalizers  =  [ ] string { } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Update ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "%s/%s/%s removing finalizers failed: %s" ,  r . Kind ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "%s/%s/%s finalizers deleted" ,  r . Kind ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						{ 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							var  list  sourcev1 . BucketList 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( "" ) ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									r . Finalizers  =  [ ] string { } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Update ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "%s/%s/%s removing finalizers failed: %s" ,  r . Kind ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "%s/%s/%s finalizers deleted" ,  r . Kind ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							if  uninstallArgs . dryRun  { 
 
					 
					 
					 
						} 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								kubectlArgs  =  append ( kubectlArgs ,  dryRun ) 
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							var  list  kustomizev1 . KustomizationList 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( "" ) ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									r . Finalizers  =  [ ] string { } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Update ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "%s/%s/%s removing finalizers failed: %s" ,  r . Kind ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "%s/%s/%s finalizers deleted" ,  r . Kind ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							if  _ ,  err  :=  utils . ExecKubectlCommand ( ctx ,  utils . ModeOS ,  rootArgs . kubeconfig ,  rootArgs . kubecontext ,  kubectlArgs ... ) ;  err  !=  nil  { 
 
					 
					 
					 
						} 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
								return  fmt . Errorf ( "uninstall failed: %w" ,  err ) 
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							var  list  helmv2 . HelmReleaseList 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  client . InNamespace ( "" ) ) ;  err  ==  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									r . Finalizers  =  [ ] string { } 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Update ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "%s/%s/%s removing finalizers failed: %s" ,  r . Kind ,  r . Namespace ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "%s/%s/%s finalizers deleted" ,  r . Kind ,  r . Namespace ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
							} 
 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						logger . Successf ( "uninstall finished" ) 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						return  nil 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					func  deleteAll ( ctx  context . Context ,  kind  string ,  dryRun  bool )  error  { 
 
					 
					 
					 
					func  uninstallCustomResourceDefinitions ( ctx  context . Context ,  kubeClient  client . Client ,  namespace  string )  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
						kubectlArgs  :=  [ ] string { 
 
					 
					 
					 
						selector  :=  client . MatchingLabels { "app.kubernetes.io/instance" :  namespace } 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							"delete" ,  kind ,  "--ignore-not-found" , 
 
					 
					 
					 
						{ 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							"--all" ,  "--all-namespaces" , 
 
					 
					 
					 
							var  list  apiextensionsv1 . CustomResourceDefinitionList 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							"--timeout" ,  rootArgs . timeout . String ( ) , 
 
					 
					 
					 
							if  err  :=  kubeClient . List ( ctx ,  & list ,  selector ) ;  err  ==  nil  { 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								for  _ ,  r  :=  range  list . Items  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									if  err  :=  kubeClient . Delete ( ctx ,  & r ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Failuref ( "CustomResourceDefinition/%s deletion failed: %s" ,  r . Name ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
										logger . Successf ( "CustomResourceDefinition/%s deleted" ,  r . Name ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
									} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
								} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						if  dryRun  { 
 
					 
					 
					 
					func  uninstallNamespace ( ctx  context . Context ,  kubeClient  client . Client ,  namespace  string )  { 
 
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
							kubectlArgs  =  append ( kubectlArgs ,  "--dry-run=server" ) 
 
					 
					 
					 
						ns  :=  corev1 . Namespace { ObjectMeta :  metav1 . ObjectMeta { Name :  namespace } } 
 
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						if  err  :=  kubeClient . Delete ( ctx ,  & ns ) ;  err  !=  nil  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							logger . Failuref ( "Namespace/%s deletion failed: %s" ,  namespace ,  err . Error ( ) ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
						}  else  { 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
							logger . Successf ( "Namespace/%s deleted" ,  namespace ) 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						} 
 
					 
					 
					 
						} 
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						_ ,  err  :=  utils . ExecKubectlCommand ( ctx ,  utils . ModeOS ,  rootArgs . kubeconfig ,  rootArgs . kubecontext ,  kubectlArgs ... ) 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
						return  err 
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} 
 
					 
					 
					 
					}