2022-11-16 17:17:28 -06:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2022-11-16 17:17:28 -06:00
package scopescmd
import (
"errors"
"fmt"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/mitchellh/cli"
"github.com/mitchellh/go-wordwrap"
"github.com/posener/complete"
)
var (
_ cli . Command = ( * DestroyKeyVersionCommand )( nil )
_ cli . CommandAutocomplete = ( * DestroyKeyVersionCommand )( nil )
)
type DestroyKeyVersionCommand struct {
* base . Command
FlagKeyVersionId string
}
func ( c * DestroyKeyVersionCommand ) Synopsis () string {
return wordwrap . WrapString ( "Destroy a key version within a scope" , base . TermWidth )
}
func ( c * DestroyKeyVersionCommand ) Help () string {
return base . WrapForHelpText ([] string {
"Usage: boundary scopes destroy-key-version [args]" ,
"" ,
" Destroys a key version in the scope. The key version must not be the currently active key version." ,
" This may start an asynchronous job to re-encrypt existing data encrypted with the key version." ,
" Use `boundary scopes list-key-version-destruction-jobs` to monitor the progress of this job. Example:" ,
"" ,
` $ boundary scopes destroy-key-version -scope-id global -key-version-id krkv_123456789` ,
"" ,
"" ,
}) + c . Flags (). Help ()
}
func ( c * DestroyKeyVersionCommand ) Flags () * base . FlagSets {
set := c . FlagSet ( base . FlagSetHTTP | base . FlagSetClient | base . FlagSetOutputFormat )
f := set . NewFlagSet ( "Command Options" )
f . StringVar ( & base . StringVar {
Name : "scope-id" ,
Target : & c . FlagScopeId ,
Usage : "The id of the scope in which the key version exists" ,
})
f . StringVar ( & base . StringVar {
Name : "key-version-id" ,
Target : & c . FlagKeyVersionId ,
Usage : "The id of the key version which should be destroyed" ,
})
return set
}
func ( c * DestroyKeyVersionCommand ) AutocompleteArgs () complete . Predictor {
return complete . PredictAnything
}
func ( c * DestroyKeyVersionCommand ) AutocompleteFlags () complete . Flags {
return c . Flags (). Completions ()
}
func ( c * DestroyKeyVersionCommand ) Run ( args [] string ) int {
f := c . Flags ()
if err := f . Parse ( args ); err != nil {
c . PrintCliError ( err )
return base . CommandUserError
}
switch {
case c . FlagScopeId == "" :
c . PrintCliError ( errors . New ( "Scope ID must be provided via -scope-id" ))
return base . CommandUserError
case c . FlagKeyVersionId == "" :
c . PrintCliError ( errors . New ( "Key Version ID must be provided via -key-version-id" ))
return base . CommandUserError
}
client , err := c . Client ()
if c . WrapperCleanupFunc != nil {
defer func () {
if err := c . WrapperCleanupFunc (); err != nil {
c . PrintCliError ( fmt . Errorf ( "Error cleaning kms wrapper: %w" , err ))
}
}()
}
if err != nil {
c . PrintCliError ( fmt . Errorf ( "Error creating API client: %w" , err ))
return base . CommandCliError
}
sClient := scopes . NewClient ( client )
result , err := sClient . DestroyKeyVersion ( c . Context , c . FlagScopeId , c . FlagKeyVersionId )
if err != nil {
if apiErr := api . AsServerError ( err ); apiErr != nil {
c . PrintApiError ( apiErr , "Error from controller when destroying key version" )
return base . CommandApiError
}
c . PrintCliError ( fmt . Errorf ( "Error trying to destroy key version: %w" , err ))
return base . CommandCliError
}
switch base . Format ( c . UI ) {
case "json" :
if ok := c . PrintJsonItem ( result . GetResponse ()); ! ok {
return base . CommandCliError
}
default :
switch result . State {
case "completed" :
c . UI . Output ( "The key version was successfully destroyed." )
case "pending" :
c . UI . Output ( "A key version destruction job has been created, which will re-encrypt existing data in the background. Use `boundary scopes list-key-version-destruction-jobs` to monitor this job. Once it has completed the key version will have been destroyed." )
default :
c . PrintCliError ( fmt . Errorf ( "unexpected state: %q" , result . State ))
return base . CommandApiError
}
}
return base . CommandSuccess
}