github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/deletecmd/delete_vault.go (about)

     1  package deletecmd
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/jenkins-x/jx/v2/pkg/cmd/helper"
     7  
     8  	"github.com/jenkins-x/jx/v2/pkg/cloud"
     9  
    10  	"github.com/jenkins-x/jx-logging/pkg/log"
    11  	awsvault "github.com/jenkins-x/jx/v2/pkg/cloud/amazon/vault"
    12  	"github.com/jenkins-x/jx/v2/pkg/cloud/gke"
    13  	gkevault "github.com/jenkins-x/jx/v2/pkg/cloud/gke/vault"
    14  	"github.com/jenkins-x/jx/v2/pkg/cmd/opts"
    15  	"github.com/jenkins-x/jx/v2/pkg/cmd/templates"
    16  	"github.com/jenkins-x/jx/v2/pkg/kube"
    17  	"github.com/jenkins-x/jx/v2/pkg/kube/naming"
    18  	"github.com/jenkins-x/jx/v2/pkg/kube/serviceaccount"
    19  	kubevault "github.com/jenkins-x/jx/v2/pkg/kube/vault"
    20  	"github.com/jenkins-x/jx/v2/pkg/util"
    21  	"github.com/pkg/errors"
    22  	"github.com/spf13/cobra"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  )
    25  
    26  // DeleteVaultOptions keeps the options of delete vault command
    27  type DeleteVaultOptions struct {
    28  	*opts.CommonOptions
    29  
    30  	Namespace            string
    31  	RemoveCloudResources bool
    32  	GKEProjectID         string
    33  	GKEZone              string
    34  }
    35  
    36  var (
    37  	deleteVaultLong = templates.LongDesc(`
    38  		Deletes a Vault
    39  	`)
    40  
    41  	deleteVaultExample = templates.Examples(`
    42  		# Deletes a Vault from namespace my-namespace
    43  		jx delete vault --namespace my-namespace my-vault
    44  	`)
    45  )
    46  
    47  // NewCmdDeleteVault builds a new delete vault command
    48  func NewCmdDeleteVault(commonOpts *opts.CommonOptions) *cobra.Command {
    49  	options := &DeleteVaultOptions{
    50  		CommonOptions: commonOpts,
    51  	}
    52  
    53  	cmd := &cobra.Command{
    54  		Use:     "vault",
    55  		Short:   "Deletes a Vault",
    56  		Long:    deleteVaultLong,
    57  		Example: deleteVaultExample,
    58  		Run: func(cmd *cobra.Command, args []string) {
    59  			options.Cmd = cmd
    60  			options.Args = args
    61  			err := options.Run()
    62  			helper.CheckErr(err)
    63  		},
    64  	}
    65  
    66  	cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", "", "Namespace from where to delete the vault")
    67  	cmd.Flags().BoolVarP(&options.RemoveCloudResources, "remove-cloud-resources", "r", false, "Remove all cloud resource allocated for the Vault")
    68  	cmd.Flags().StringVarP(&options.GKEProjectID, "gke-project-id", "", "", "Google Project ID to use for Vault backend")
    69  	cmd.Flags().StringVarP(&options.GKEZone, "gke-zone", "", "", "The zone (e.g. us-central1-a) where Vault will store the encrypted data")
    70  	return cmd
    71  }
    72  
    73  // Run implements the delete vault command
    74  func (o *DeleteVaultOptions) Run() error {
    75  	if len(o.Args) != 1 {
    76  		return fmt.Errorf("Missing vault name")
    77  	}
    78  	vaultName := o.Args[0]
    79  
    80  	client, ns, err := o.KubeClientAndNamespace()
    81  	if err != nil {
    82  		return errors.Wrap(err, "creating kubernetes client")
    83  	}
    84  
    85  	if o.Namespace == "" {
    86  		o.Namespace = ns
    87  	}
    88  
    89  	teamSettings, err := o.TeamSettings()
    90  	if err != nil {
    91  		return errors.Wrap(err, "retrieving the team settings")
    92  	}
    93  
    94  	vaultOperatorClient, err := o.VaultOperatorClient()
    95  	if err != nil {
    96  		return errors.Wrap(err, "creating vault operator client")
    97  	}
    98  
    99  	v, err := kubevault.GetVault(vaultOperatorClient, vaultName, o.Namespace)
   100  	if err != nil {
   101  		return fmt.Errorf("vault '%s' not found in namespace '%s'", vaultName, o.Namespace)
   102  	}
   103  
   104  	err = kubevault.DeleteVault(vaultOperatorClient, vaultName, o.Namespace)
   105  	if err != nil {
   106  		return errors.Wrap(err, "deleting the vault resource")
   107  	}
   108  
   109  	err = kube.DeleteIngress(client, o.Namespace, vaultName)
   110  	if err != nil {
   111  		return errors.Wrapf(err, "deleting the vault ingress '%s'", vaultName)
   112  	}
   113  
   114  	authServiceAccountName := kubevault.GetAuthSaName(*v)
   115  	err = serviceaccount.DeleteServiceAccount(client, o.Namespace, authServiceAccountName)
   116  	if err != nil {
   117  		return errors.Wrapf(err, "deleting the vault auth service account '%s'", authServiceAccountName)
   118  	}
   119  
   120  	var secretName string
   121  	if teamSettings.KubeProvider == cloud.GKE {
   122  		secretName = gke.GcpServiceAccountSecretName(vaultName)
   123  	}
   124  	if teamSettings.KubeProvider == cloud.AWS || teamSettings.KubeProvider == cloud.EKS {
   125  		secretName = awsvault.AwsServiceAccountSecretName(vaultName)
   126  	}
   127  	err = client.CoreV1().Secrets(o.Namespace).Delete(secretName, &metav1.DeleteOptions{})
   128  	if err != nil {
   129  		return errors.Wrapf(err, "deleting secret '%s' where GCP service account is stored", secretName)
   130  	}
   131  	err = kube.DeleteClusterRoleBinding(client, vaultName)
   132  	if err != nil {
   133  		return errors.Wrapf(err, "deleting the cluster role binding '%s' for vault", vaultName)
   134  	}
   135  
   136  	log.Logger().Infof("Vault %s deleted", util.ColorInfo(vaultName))
   137  
   138  	if o.RemoveCloudResources {
   139  		if teamSettings.KubeProvider == cloud.GKE {
   140  			log.Logger().Infof("Removing GCP resources allocated for Vault...")
   141  			err := o.removeGCPResources(vaultName)
   142  			if err != nil {
   143  				return errors.Wrap(err, "removing GCP resource")
   144  			}
   145  			log.Logger().Infof("Cloud resources allocated for vault %s deleted", util.ColorInfo(vaultName))
   146  		}
   147  	}
   148  
   149  	return nil
   150  }
   151  
   152  func (o *DeleteVaultOptions) removeGCPResources(vaultName string) error {
   153  	err := o.GCloud().Login("", true)
   154  	if err != nil {
   155  		return errors.Wrap(err, "login into GCP")
   156  	}
   157  
   158  	if o.GKEProjectID == "" {
   159  		projectID, err := o.GetGoogleProjectID("")
   160  		if err != nil {
   161  			return err
   162  		}
   163  		o.GKEProjectID = projectID
   164  	}
   165  	err = o.RunCommandVerbose("gcloud", "config", "set", "project", o.GKEProjectID)
   166  	if err != nil {
   167  		return err
   168  	}
   169  
   170  	if o.GKEZone == "" {
   171  		zone, err := o.GetGoogleZone(o.GKEProjectID, "")
   172  		if err != nil {
   173  			return err
   174  		}
   175  		o.GKEZone = zone
   176  	}
   177  
   178  	sa := naming.ToValidGCPServiceAccount(gke.ServiceAccountName(vaultName, gkevault.DefaultVaultAbbreviation))
   179  	err = o.GCloud().DeleteServiceAccount(sa, o.GKEProjectID, gkevault.ServiceAccountRoles)
   180  	if err != nil {
   181  		return errors.Wrapf(err, "deleting the GCP service account '%s'", sa)
   182  	}
   183  	log.Logger().Infof("GCP service account %s deleted", util.ColorInfo(sa))
   184  
   185  	bucket := gke.BucketName(vaultName)
   186  	err = o.GCloud().DeleteAllObjectsInBucket(bucket)
   187  	if err != nil {
   188  		return errors.Wrapf(err, "deleting all objects in GCS bucket '%s'", bucket)
   189  	}
   190  
   191  	log.Logger().Infof("GCS bucket %s deleted", util.ColorInfo(bucket))
   192  
   193  	return nil
   194  }