2012-07-23 10:18:51 +04:00
/*
* virsh - secret . c : Commands to manage secret
*
2016-01-09 16:36:29 +03:00
* Copyright ( C ) 2005 , 2007 - 2016 Red Hat , Inc .
2012-07-23 10:18:51 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2012-09-21 02:30:55 +04:00
* License along with this library . If not , see
2012-07-23 10:18:51 +04:00
* < http : //www.gnu.org/licenses/>.
*/
2012-08-21 03:14:37 +04:00
# include <config.h>
# include "virsh-secret.h"
2020-01-24 17:24:49 +03:00
# include "virsh-util.h"
2012-08-21 03:14:37 +04:00
# include "internal.h"
2012-12-04 16:04:07 +04:00
# include "virbuffer.h"
2012-12-12 22:06:53 +04:00
# include "viralloc.h"
2013-05-09 22:59:04 +04:00
# include "virfile.h"
2012-12-13 21:44:57 +04:00
# include "virutil.h"
2017-09-15 21:55:46 +03:00
# include "virsecret.h"
2016-05-13 14:15:15 +03:00
# include "virstring.h"
2016-12-22 19:39:43 +03:00
# include "virtime.h"
2018-09-21 17:17:14 +03:00
# include "vsh-table.h"
2019-04-01 13:14:26 +03:00
# include "virenum.h"
2012-08-21 03:14:37 +04:00
2012-07-23 10:18:51 +04:00
static virSecretPtr
2015-06-15 19:53:58 +03:00
virshCommandOptSecret ( vshControl * ctl , const vshCmd * cmd , const char * * name )
2012-07-23 10:18:51 +04:00
{
virSecretPtr secret = NULL ;
const char * n = NULL ;
const char * optname = " secret " ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:18:51 +04:00
2013-01-21 21:28:47 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , optname , & n ) < 0 )
2012-07-23 10:18:51 +04:00
return NULL ;
vshDebug ( ctl , VSH_ERR_DEBUG ,
" %s: found option <%s>: %s \n " , cmd - > def - > name , optname , n ) ;
if ( name ! = NULL )
* name = n ;
2015-06-15 19:53:58 +03:00
secret = virSecretLookupByUUIDString ( priv - > conn , n ) ;
2012-07-23 10:18:51 +04:00
if ( secret = = NULL )
vshError ( ctl , _ ( " failed to get secret '%s' " ) , n ) ;
return secret ;
}
/*
* " secret-define " command
*/
static const vshCmdInfo info_secret_define [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " define or modify a secret from an XML file " )
} ,
{ . name = " desc " ,
. data = N_ ( " Define or modify a secret. " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static const vshCmdOptDef opts_secret_define [ ] = {
2016-01-09 16:36:29 +03:00
VIRSH_COMMON_OPT_FILE ( N_ ( " file containing secret attributes in XML " ) ) ,
2013-01-14 18:38:52 +04:00
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static bool
cmdSecretDefine ( vshControl * ctl , const vshCmd * cmd )
{
const char * from = NULL ;
char * buffer ;
virSecretPtr res ;
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
2013-01-21 21:28:47 +04:00
bool ret = false ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:18:51 +04:00
2013-01-21 21:28:47 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , " file " , & from ) < 0 )
2012-07-23 10:18:51 +04:00
return false ;
virsh: use common namespacing
Convert the exported items in virsh.h to use a common 'vsh' prefix.
* tools/virsh.h (VIRSH_MAX_XML_FILE): Rename...
(VSH_MAX_XML_FILE): ...and parenthesize.
(DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype.
(editWriteToTempFile, editFile, editReadBackFile, prettyCapacity)
(virshReportError): Rename...
(vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile)
(vshPrettyCapacity, vshReportError): ...into vsh namespace.
(jobWatchTimeoutFunc): Move to virsh-domain.c.
* tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC.
(main): Inline former CTRL_CLOSE_BRACKET.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Make static.
(prettyCapacity, virshReportError, editWriteToTempFile, editFile):
Fix naming, and adjust usage.
(vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust
usage.
* tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare)
(cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice)
(cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount)
(cmdAttachDevice, cmdDomjobinfo): Likewise.
* tools/virsh-edit.c (do): Likewise.
* tools/virsh-interface.c (cmdInterfaceDefine): Likewise.
* tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine):
Likewise.
* tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise.
* tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise.
* tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine)
(cmdPoolDiscoverSources, cmdPoolList): Likewise.
* tools/virsh-secret.c (cmdSecretDefine): Likewise.
* tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate)
(vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent)
(vshGetSnapshotParent): Likewise.
* tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom)
(cmdVolInfo, cmdVolList): Likewise.
2012-08-19 08:10:17 +04:00
if ( virFileReadAll ( from , VSH_MAX_XML_FILE , & buffer ) < 0 )
2012-07-23 10:18:51 +04:00
return false ;
2015-06-15 19:53:58 +03:00
if ( ! ( res = virSecretDefineXML ( priv - > conn , buffer , 0 ) ) ) {
2012-07-23 10:18:51 +04:00
vshError ( ctl , _ ( " Failed to set attributes from %s " ) , from ) ;
2013-01-21 21:28:47 +04:00
goto cleanup ;
2012-07-23 10:18:51 +04:00
}
2013-01-21 21:28:47 +04:00
2012-07-23 10:18:51 +04:00
if ( virSecretGetUUIDString ( res , & ( uuid [ 0 ] ) ) < 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to get UUID of created secret " ) ) ;
2013-01-21 21:28:47 +04:00
goto cleanup ;
2012-07-23 10:18:51 +04:00
}
2013-01-21 21:28:47 +04:00
2016-08-24 17:14:23 +03:00
vshPrintExtra ( ctl , _ ( " Secret %s created \n " ) , uuid ) ;
2013-01-21 21:28:47 +04:00
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2013-01-21 21:28:47 +04:00
VIR_FREE ( buffer ) ;
2020-01-24 17:24:49 +03:00
virshSecretFree ( res ) ;
2013-01-21 21:28:47 +04:00
return ret ;
2012-07-23 10:18:51 +04:00
}
/*
* " secret-dumpxml " command
*/
static const vshCmdInfo info_secret_dumpxml [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " secret attributes in XML " )
} ,
{ . name = " desc " ,
. data = N_ ( " Output attributes of a secret as an XML dump to stdout. " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static const vshCmdOptDef opts_secret_dumpxml [ ] = {
2013-01-14 18:38:52 +04:00
{ . name = " secret " ,
. type = VSH_OT_DATA ,
. flags = VSH_OFLAG_REQ ,
2018-01-12 17:00:40 +03:00
. help = N_ ( " secret UUID " ) ,
. completer = virshSecretUUIDCompleter ,
2013-01-14 18:38:52 +04:00
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static bool
cmdSecretDumpXML ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret ;
bool ret = false ;
char * xml ;
2015-06-15 19:53:58 +03:00
secret = virshCommandOptSecret ( ctl , cmd , NULL ) ;
2012-07-23 10:18:51 +04:00
if ( secret = = NULL )
return false ;
xml = virSecretGetXMLDesc ( secret , 0 ) ;
if ( xml = = NULL )
goto cleanup ;
vshPrint ( ctl , " %s " , xml ) ;
VIR_FREE ( xml ) ;
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2020-01-24 17:24:49 +03:00
virshSecretFree ( secret ) ;
2012-07-23 10:18:51 +04:00
return ret ;
}
/*
* " secret-set-value " command
*/
static const vshCmdInfo info_secret_set_value [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " set a secret value " )
} ,
{ . name = " desc " ,
. data = N_ ( " Set a secret value. " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static const vshCmdOptDef opts_secret_set_value [ ] = {
2013-01-14 18:38:52 +04:00
{ . name = " secret " ,
. type = VSH_OT_DATA ,
. flags = VSH_OFLAG_REQ ,
2018-01-12 17:00:40 +03:00
. help = N_ ( " secret UUID " ) ,
. completer = virshSecretUUIDCompleter ,
2013-01-14 18:38:52 +04:00
} ,
2020-01-10 17:54:05 +03:00
{ . name = " file " ,
. type = VSH_OT_STRING ,
. flags = VSH_OFLAG_REQ_OPT ,
. help = N_ ( " read secret from file " ) ,
} ,
2020-01-24 18:28:19 +03:00
{ . name = " plain " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " read the secret from file without converting from base64 " )
} ,
2020-01-24 18:37:27 +03:00
{ . name = " interactive " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " read the secret from the terminal " )
} ,
2013-01-14 18:38:52 +04:00
{ . name = " base64 " ,
2020-01-10 17:54:05 +03:00
. type = VSH_OT_STRING ,
2013-01-14 18:38:52 +04:00
. help = N_ ( " base64-encoded secret value " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static bool
cmdSecretSetValue ( vshControl * ctl , const vshCmd * cmd )
{
2020-01-24 17:42:02 +03:00
g_autoptr ( virshSecret ) secret = NULL ;
2012-07-23 10:18:51 +04:00
const char * base64 = NULL ;
2020-01-10 17:54:05 +03:00
const char * filename = NULL ;
char * file_buf = NULL ;
size_t file_len = 0 ;
2019-09-16 15:29:20 +03:00
unsigned char * value ;
2020-01-10 17:54:05 +03:00
size_t value_size ;
2020-01-24 18:28:19 +03:00
bool plain = vshCommandOptBool ( cmd , " plain " ) ;
2020-01-24 18:37:27 +03:00
bool interactive = vshCommandOptBool ( cmd , " interactive " ) ;
2012-07-23 10:18:51 +04:00
int res ;
2020-01-10 17:54:05 +03:00
VSH_EXCLUSIVE_OPTIONS ( " file " , " base64 " ) ;
2020-01-24 18:28:19 +03:00
VSH_EXCLUSIVE_OPTIONS ( " plain " , " base64 " ) ;
2020-01-24 18:37:27 +03:00
VSH_EXCLUSIVE_OPTIONS ( " interactive " , " base64 " ) ;
VSH_EXCLUSIVE_OPTIONS ( " interactive " , " plain " ) ;
VSH_EXCLUSIVE_OPTIONS ( " interactive " , " file " ) ;
2020-01-10 17:54:05 +03:00
2015-06-15 19:53:58 +03:00
if ( ! ( secret = virshCommandOptSecret ( ctl , cmd , NULL ) ) )
2012-07-23 10:18:51 +04:00
return false ;
2013-01-21 21:28:47 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , " base64 " , & base64 ) < 0 )
2020-01-24 17:42:02 +03:00
return false ;
2012-07-23 10:18:51 +04:00
2020-01-10 17:54:05 +03:00
if ( vshCommandOptStringReq ( ctl , cmd , " file " , & filename ) < 0 )
return false ;
2020-01-24 18:37:27 +03:00
if ( ! base64 & & ! filename & & ! interactive ) {
2020-01-10 17:54:05 +03:00
vshError ( ctl , _ ( " Input secret value is missing " ) ) ;
return false ;
}
2020-01-24 18:16:27 +03:00
/* warn users that the --base64 option passed from command line is wrong */
if ( base64 )
vshError ( ctl , _ ( " Passing secret value as command-line argument is insecure! " ) ) ;
2020-01-10 17:54:05 +03:00
if ( filename ) {
ssize_t read_ret ;
if ( ( read_ret = virFileReadAll ( filename , 1024 , & file_buf ) ) < 0 ) {
vshSaveLibvirtError ( ) ;
return false ;
}
file_len = read_ret ;
base64 = file_buf ;
}
2020-01-24 18:37:27 +03:00
if ( interactive ) {
vshPrint ( ctl , " %s " , _ ( " Enter new value for secret: " ) ) ;
fflush ( stdout ) ;
2020-01-14 13:40:52 +03:00
if ( ! ( file_buf = virGetPassword ( ) ) ) {
2020-01-24 18:37:27 +03:00
vshError ( ctl , " %s " , _ ( " Failed to read secret " ) ) ;
return false ;
}
file_len = strlen ( file_buf ) ;
plain = true ;
}
2020-01-24 18:28:19 +03:00
if ( plain ) {
value = g_steal_pointer ( & file_buf ) ;
value_size = file_len ;
file_len = 0 ;
} else {
value = g_base64_decode ( base64 , & value_size ) ;
}
2012-07-23 10:18:51 +04:00
2019-09-16 15:29:20 +03:00
res = virSecretSetValue ( secret , value , value_size , 0 ) ;
2020-01-10 17:54:05 +03:00
VIR_DISPOSE_N ( value , value_size ) ;
VIR_DISPOSE_N ( file_buf , file_len ) ;
2012-07-23 10:18:51 +04:00
if ( res ! = 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to set secret value " ) ) ;
2020-01-24 17:42:02 +03:00
return false ;
2012-07-23 10:18:51 +04:00
}
2016-08-24 17:14:23 +03:00
vshPrintExtra ( ctl , " %s " , _ ( " Secret value set \n " ) ) ;
2020-01-24 17:42:02 +03:00
return true ;
2012-07-23 10:18:51 +04:00
}
/*
* " secret-get-value " command
*/
static const vshCmdInfo info_secret_get_value [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " Output a secret value " )
} ,
{ . name = " desc " ,
. data = N_ ( " Output a secret value to stdout. " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static const vshCmdOptDef opts_secret_get_value [ ] = {
2013-01-14 18:38:52 +04:00
{ . name = " secret " ,
. type = VSH_OT_DATA ,
. flags = VSH_OFLAG_REQ ,
2018-01-12 17:00:40 +03:00
. help = N_ ( " secret UUID " ) ,
. completer = virshSecretUUIDCompleter ,
2013-01-14 18:38:52 +04:00
} ,
2020-01-10 17:12:16 +03:00
{ . name = " plain " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " get value without converting to base64 " )
} ,
2013-01-14 18:38:52 +04:00
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static bool
cmdSecretGetValue ( vshControl * ctl , const vshCmd * cmd )
{
2020-01-24 17:42:02 +03:00
g_autoptr ( virshSecret ) secret = NULL ;
2019-04-01 16:04:54 +03:00
VIR_AUTODISPOSE_STR base64 = NULL ;
2012-07-23 10:18:51 +04:00
unsigned char * value ;
size_t value_size ;
2020-01-10 17:12:16 +03:00
bool plain = vshCommandOptBool ( cmd , " plain " ) ;
2012-07-23 10:18:51 +04:00
2020-01-24 17:42:02 +03:00
if ( ! ( secret = virshCommandOptSecret ( ctl , cmd , NULL ) ) )
2012-07-23 10:18:51 +04:00
return false ;
2020-01-24 17:42:02 +03:00
if ( ! ( value = virSecretGetValue ( secret , & value_size , 0 ) ) )
return false ;
2012-07-23 10:18:51 +04:00
2020-01-10 17:12:16 +03:00
if ( plain ) {
if ( fwrite ( value , 1 , value_size , stdout ) ! = value_size ) {
VIR_DISPOSE_N ( value , value_size ) ;
vshError ( ctl , " failed to write secret " ) ;
return false ;
}
} else {
base64 = g_base64_encode ( value , value_size ) ;
2016-05-13 14:15:15 +03:00
2020-01-10 17:12:16 +03:00
vshPrint ( ctl , " %s " , base64 ) ;
}
2012-07-23 10:18:51 +04:00
2016-05-13 14:15:15 +03:00
VIR_DISPOSE_N ( value , value_size ) ;
2020-01-24 17:42:02 +03:00
return true ;
2012-07-23 10:18:51 +04:00
}
/*
* " secret-undefine " command
*/
static const vshCmdInfo info_secret_undefine [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " undefine a secret " )
} ,
{ . name = " desc " ,
. data = N_ ( " Undefine a secret. " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static const vshCmdOptDef opts_secret_undefine [ ] = {
2013-01-14 18:38:52 +04:00
{ . name = " secret " ,
. type = VSH_OT_DATA ,
. flags = VSH_OFLAG_REQ ,
2018-01-12 17:00:40 +03:00
. help = N_ ( " secret UUID " ) ,
. completer = virshSecretUUIDCompleter ,
2013-01-14 18:38:52 +04:00
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
static bool
cmdSecretUndefine ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret ;
bool ret = false ;
const char * uuid ;
2015-06-15 19:53:58 +03:00
secret = virshCommandOptSecret ( ctl , cmd , & uuid ) ;
2012-07-23 10:18:51 +04:00
if ( secret = = NULL )
return false ;
if ( virSecretUndefine ( secret ) < 0 ) {
vshError ( ctl , _ ( " Failed to delete secret %s " ) , uuid ) ;
goto cleanup ;
}
2016-08-24 17:14:23 +03:00
vshPrintExtra ( ctl , _ ( " Secret %s deleted \n " ) , uuid ) ;
2012-07-23 10:18:51 +04:00
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2020-01-24 17:24:49 +03:00
virshSecretFree ( secret ) ;
2012-07-23 10:18:51 +04:00
return ret ;
}
2012-09-14 12:38:52 +04:00
static int
2015-06-15 19:53:58 +03:00
virshSecretSorter ( const void * a , const void * b )
2012-09-14 12:38:52 +04:00
{
virSecretPtr * sa = ( virSecretPtr * ) a ;
virSecretPtr * sb = ( virSecretPtr * ) b ;
char uuid_sa [ VIR_UUID_STRING_BUFLEN ] ;
char uuid_sb [ VIR_UUID_STRING_BUFLEN ] ;
if ( * sa & & ! * sb )
return - 1 ;
if ( ! * sa )
return * sb ! = NULL ;
virSecretGetUUIDString ( * sa , uuid_sa ) ;
virSecretGetUUIDString ( * sb , uuid_sb ) ;
return vshStrcasecmp ( uuid_sa , uuid_sb ) ;
}
2015-06-15 19:53:58 +03:00
struct virshSecretList {
2012-09-14 12:38:52 +04:00
virSecretPtr * secrets ;
size_t nsecrets ;
} ;
2015-06-15 19:53:58 +03:00
typedef struct virshSecretList * virshSecretListPtr ;
2012-09-14 12:38:52 +04:00
static void
2015-06-15 19:53:58 +03:00
virshSecretListFree ( virshSecretListPtr list )
2012-09-14 12:38:52 +04:00
{
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2012-09-14 12:38:52 +04:00
2013-08-27 15:27:50 +04:00
if ( list & & list - > secrets ) {
2020-01-24 17:24:49 +03:00
for ( i = 0 ; i < list - > nsecrets ; i + + )
virshSecretFree ( list - > secrets [ i ] ) ;
2012-09-14 12:38:52 +04:00
VIR_FREE ( list - > secrets ) ;
}
VIR_FREE ( list ) ;
}
2015-06-15 19:53:58 +03:00
static virshSecretListPtr
virshSecretListCollect ( vshControl * ctl ,
unsigned int flags )
2012-09-14 12:38:52 +04:00
{
2015-06-15 19:53:58 +03:00
virshSecretListPtr list = vshMalloc ( ctl , sizeof ( * list ) ) ;
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2012-09-14 12:38:52 +04:00
int ret ;
virSecretPtr secret ;
bool success = false ;
size_t deleted = 0 ;
int nsecrets = 0 ;
char * * uuids = NULL ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-09-14 12:38:52 +04:00
/* try the list with flags support (0.10.2 and later) */
2015-06-15 19:53:58 +03:00
if ( ( ret = virConnectListAllSecrets ( priv - > conn ,
2012-09-14 12:38:52 +04:00
& list - > secrets ,
flags ) ) > = 0 ) {
list - > nsecrets = ret ;
goto finished ;
}
/* check if the command is actually supported */
if ( last_error & & last_error - > code = = VIR_ERR_NO_SUPPORT )
goto fallback ;
/* there was an error during the call */
vshError ( ctl , " %s " , _ ( " Failed to list node secrets " ) ) ;
goto cleanup ;
2014-03-25 10:53:59 +04:00
fallback :
2012-09-14 12:38:52 +04:00
/* fall back to old method (0.10.1 and older) */
vshResetLibvirtError ( ) ;
if ( flags ) {
vshError ( ctl , " %s " , _ ( " Filtering is not supported by this libvirt " ) ) ;
goto cleanup ;
}
2015-06-15 19:53:58 +03:00
nsecrets = virConnectNumOfSecrets ( priv - > conn ) ;
2012-09-14 12:38:52 +04:00
if ( nsecrets < 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to count secrets " ) ) ;
goto cleanup ;
}
if ( nsecrets = = 0 )
return list ;
uuids = vshMalloc ( ctl , sizeof ( char * ) * nsecrets ) ;
2015-06-15 19:53:58 +03:00
nsecrets = virConnectListSecrets ( priv - > conn , uuids , nsecrets ) ;
2012-09-14 12:38:52 +04:00
if ( nsecrets < 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to list secrets " ) ) ;
goto cleanup ;
}
list - > secrets = vshMalloc ( ctl , sizeof ( virSecretPtr ) * ( nsecrets ) ) ;
list - > nsecrets = 0 ;
/* get the secrets */
2013-05-21 11:44:53 +04:00
for ( i = 0 ; i < nsecrets ; i + + ) {
2015-06-15 19:53:58 +03:00
if ( ! ( secret = virSecretLookupByUUIDString ( priv - > conn , uuids [ i ] ) ) )
2012-09-14 12:38:52 +04:00
continue ;
list - > secrets [ list - > nsecrets + + ] = secret ;
}
/* truncate secrets that weren't found */
deleted = nsecrets - list - > nsecrets ;
2014-03-25 10:53:59 +04:00
finished :
2012-09-14 12:38:52 +04:00
/* sort the list */
if ( list - > secrets & & list - > nsecrets )
qsort ( list - > secrets , list - > nsecrets ,
2015-06-15 19:53:58 +03:00
sizeof ( * list - > secrets ) , virshSecretSorter ) ;
2012-09-14 12:38:52 +04:00
/* truncate the list for not found secret objects */
if ( deleted )
VIR_SHRINK_N ( list - > secrets , list - > nsecrets , deleted ) ;
success = true ;
2014-03-25 10:53:59 +04:00
cleanup :
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
if ( nsecrets > 0 ) {
for ( i = 0 ; i < nsecrets ; i + + )
VIR_FREE ( uuids [ i ] ) ;
VIR_FREE ( uuids ) ;
}
2012-09-14 12:38:52 +04:00
if ( ! success ) {
2015-06-15 19:53:58 +03:00
virshSecretListFree ( list ) ;
2012-09-14 12:38:52 +04:00
list = NULL ;
}
return list ;
}
2012-07-23 10:18:51 +04:00
/*
* " secret-list " command
*/
static const vshCmdInfo info_secret_list [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " list secrets " )
} ,
{ . name = " desc " ,
. data = N_ ( " Returns a list of secrets " )
} ,
{ . name = NULL }
2012-07-23 10:18:51 +04:00
} ;
2012-09-14 12:38:52 +04:00
static const vshCmdOptDef opts_secret_list [ ] = {
2013-01-14 18:38:52 +04:00
{ . name = " ephemeral " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " list ephemeral secrets " )
} ,
{ . name = " no-ephemeral " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " list non-ephemeral secrets " )
} ,
{ . name = " private " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " list private secrets " )
} ,
{ . name = " no-private " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " list non-private secrets " )
} ,
{ . name = NULL }
2012-09-14 12:38:52 +04:00
} ;
2012-07-23 10:18:51 +04:00
static bool
2019-10-14 15:44:29 +03:00
cmdSecretList ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:18:51 +04:00
{
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2015-06-15 19:53:58 +03:00
virshSecretListPtr list = NULL ;
2012-09-14 12:38:52 +04:00
bool ret = false ;
unsigned int flags = 0 ;
2018-09-21 17:17:14 +03:00
vshTablePtr table = NULL ;
2012-07-23 10:18:51 +04:00
2012-09-14 12:38:52 +04:00
if ( vshCommandOptBool ( cmd , " ephemeral " ) )
flags | = VIR_CONNECT_LIST_SECRETS_EPHEMERAL ;
2012-07-23 10:18:51 +04:00
2012-09-14 12:38:52 +04:00
if ( vshCommandOptBool ( cmd , " no-ephemeral " ) )
flags | = VIR_CONNECT_LIST_SECRETS_NO_EPHEMERAL ;
if ( vshCommandOptBool ( cmd , " private " ) )
flags | = VIR_CONNECT_LIST_SECRETS_PRIVATE ;
2012-07-23 10:18:51 +04:00
2012-09-14 12:38:52 +04:00
if ( vshCommandOptBool ( cmd , " no-private " ) )
flags | = VIR_CONNECT_LIST_SECRETS_NO_PRIVATE ;
2015-06-15 19:53:58 +03:00
if ( ! ( list = virshSecretListCollect ( ctl , flags ) ) )
2012-09-14 12:38:52 +04:00
return false ;
2012-07-23 10:18:51 +04:00
2018-09-21 17:17:14 +03:00
table = vshTableNew ( _ ( " UUID " ) , _ ( " Usage " ) , NULL ) ;
if ( ! table )
goto cleanup ;
2012-07-23 10:18:51 +04:00
2012-09-14 12:38:52 +04:00
for ( i = 0 ; i < list - > nsecrets ; i + + ) {
virSecretPtr sec = list - > secrets [ i ] ;
2013-08-06 15:49:23 +04:00
int usageType = virSecretGetUsageType ( sec ) ;
2014-05-14 23:48:15 +04:00
const char * usageStr = virSecretUsageTypeToString ( usageType ) ;
2012-09-14 12:38:52 +04:00
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
2018-09-21 17:17:14 +03:00
virBuffer buf = VIR_BUFFER_INITIALIZER ;
2019-10-15 16:16:31 +03:00
g_autofree char * usage = NULL ;
2013-08-06 15:49:23 +04:00
2014-04-29 06:10:18 +04:00
if ( virSecretGetUUIDString ( sec , uuid ) < 0 ) {
2012-09-14 12:38:52 +04:00
vshError ( ctl , " %s " , _ ( " Failed to get uuid of secret " ) ) ;
goto cleanup ;
}
2012-07-23 10:18:51 +04:00
if ( usageType ) {
2018-09-21 17:17:14 +03:00
virBufferStrcat ( & buf , usageStr , " " ,
virSecretGetUsageID ( sec ) , NULL ) ;
usage = virBufferContentAndReset ( & buf ) ;
if ( ! usage )
goto cleanup ;
if ( vshTableRowAppend ( table , uuid , usage , NULL ) < 0 )
goto cleanup ;
2012-07-23 10:18:51 +04:00
} else {
2018-09-21 17:17:14 +03:00
if ( vshTableRowAppend ( table , uuid , _ ( " Unused " ) , NULL ) < 0 )
goto cleanup ;
2012-07-23 10:18:51 +04:00
}
}
2012-09-14 12:38:52 +04:00
2018-09-21 17:17:14 +03:00
vshTablePrintToStdout ( table , ctl ) ;
2012-09-14 12:38:52 +04:00
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2018-09-21 17:17:14 +03:00
vshTableFree ( table ) ;
2015-06-15 19:53:58 +03:00
virshSecretListFree ( list ) ;
2012-09-14 12:38:52 +04:00
return ret ;
2012-07-23 10:18:51 +04:00
}
2012-07-23 11:19:04 +04:00
2016-12-22 19:39:43 +03:00
/*
* " Secret-event " command
*/
2019-01-20 19:04:56 +03:00
VIR_ENUM_DECL ( virshSecretEvent ) ;
2016-12-22 19:39:43 +03:00
VIR_ENUM_IMPL ( virshSecretEvent ,
VIR_SECRET_EVENT_LAST ,
N_ ( " Defined " ) ,
2019-01-20 19:30:15 +03:00
N_ ( " Undefined " ) ) ;
2016-12-22 19:39:43 +03:00
static const char *
virshSecretEventToString ( int event )
{
const char * str = virshSecretEventTypeToString ( event ) ;
return str ? _ ( str ) : _ ( " unknown " ) ;
}
struct virshSecretEventData {
vshControl * ctl ;
bool loop ;
bool timestamp ;
int count ;
2018-05-23 09:32:39 +03:00
virshSecretEventCallback * cb ;
2016-12-22 19:39:43 +03:00
} ;
typedef struct virshSecretEventData virshSecretEventData ;
static void
2019-10-14 15:44:29 +03:00
vshEventLifecyclePrint ( virConnectPtr conn G_GNUC_UNUSED ,
2016-12-22 19:39:43 +03:00
virSecretPtr secret ,
int event ,
2019-10-14 15:44:29 +03:00
int detail G_GNUC_UNUSED ,
2016-12-22 19:39:43 +03:00
void * opaque )
{
virshSecretEventData * data = opaque ;
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
if ( ! data - > loop & & data - > count )
return ;
virSecretGetUUIDString ( secret , uuid ) ;
if ( data - > timestamp ) {
char timestamp [ VIR_TIME_STRING_BUFLEN ] ;
if ( virTimeStringNowRaw ( timestamp ) < 0 )
timestamp [ 0 ] = ' \0 ' ;
vshPrint ( data - > ctl , _ ( " %s: event 'lifecycle' for secret %s: %s \n " ) ,
timestamp , uuid , virshSecretEventToString ( event ) ) ;
} else {
vshPrint ( data - > ctl , _ ( " event 'lifecycle' for secret %s: %s \n " ) ,
uuid , virshSecretEventToString ( event ) ) ;
}
data - > count + + ;
if ( ! data - > loop )
vshEventDone ( data - > ctl ) ;
}
2017-01-05 16:51:07 +03:00
static void
2019-10-14 15:44:29 +03:00
vshEventGenericPrint ( virConnectPtr conn G_GNUC_UNUSED ,
2017-01-05 16:51:07 +03:00
virSecretPtr secret ,
void * opaque )
{
virshSecretEventData * data = opaque ;
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
if ( ! data - > loop & & data - > count )
return ;
virSecretGetUUIDString ( secret , uuid ) ;
if ( data - > timestamp ) {
char timestamp [ VIR_TIME_STRING_BUFLEN ] ;
if ( virTimeStringNowRaw ( timestamp ) < 0 )
timestamp [ 0 ] = ' \0 ' ;
vshPrint ( data - > ctl , _ ( " %s: event '%s' for secret %s \n " ) ,
timestamp ,
data - > cb - > name ,
uuid ) ;
} else {
vshPrint ( data - > ctl , _ ( " event '%s' for secret %s \n " ) ,
data - > cb - > name ,
uuid ) ;
}
data - > count + + ;
if ( ! data - > loop )
vshEventDone ( data - > ctl ) ;
}
2018-05-23 09:32:39 +03:00
virshSecretEventCallback virshSecretEventCallbacks [ ] = {
2016-12-22 19:39:43 +03:00
{ " lifecycle " ,
VIR_SECRET_EVENT_CALLBACK ( vshEventLifecyclePrint ) , } ,
2017-01-05 16:51:07 +03:00
{ " value-changed " , vshEventGenericPrint , } ,
2016-12-22 19:39:43 +03:00
} ;
2020-01-09 13:39:55 +03:00
G_STATIC_ASSERT ( VIR_SECRET_EVENT_ID_LAST = = G_N_ELEMENTS ( virshSecretEventCallbacks ) ) ;
2016-12-22 19:39:43 +03:00
static const vshCmdInfo info_secret_event [ ] = {
{ . name = " help " ,
. data = N_ ( " Secret Events " )
} ,
{ . name = " desc " ,
. data = N_ ( " List event types, or wait for secret events to occur " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_secret_event [ ] = {
{ . name = " secret " ,
. type = VSH_OT_STRING ,
2018-01-12 17:00:40 +03:00
. help = N_ ( " filter by secret name or uuid " ) ,
. completer = virshSecretUUIDCompleter ,
2016-12-22 19:39:43 +03:00
} ,
{ . name = " event " ,
. type = VSH_OT_STRING ,
2018-05-23 09:32:40 +03:00
. completer = virshSecretEventNameCompleter ,
2016-12-22 19:39:43 +03:00
. help = N_ ( " which event type to wait for " )
} ,
{ . name = " loop " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " loop until timeout or interrupt, rather than one-shot " )
} ,
{ . name = " timeout " ,
. type = VSH_OT_INT ,
. help = N_ ( " timeout seconds " )
} ,
{ . name = " list " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " list valid event types " )
} ,
{ . name = " timestamp " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " show timestamp for each printed event " )
} ,
{ . name = NULL }
} ;
static bool
cmdSecretEvent ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret = NULL ;
bool ret = false ;
int eventId = - 1 ;
int timeout = 0 ;
virshSecretEventData data ;
const char * eventName = NULL ;
int event ;
virshControlPtr priv = ctl - > privData ;
if ( vshCommandOptBool ( cmd , " list " ) ) {
size_t i ;
for ( i = 0 ; i < VIR_SECRET_EVENT_ID_LAST ; i + + )
2018-05-23 09:32:39 +03:00
vshPrint ( ctl , " %s \n " , virshSecretEventCallbacks [ i ] . name ) ;
2016-12-22 19:39:43 +03:00
return true ;
}
if ( vshCommandOptStringReq ( ctl , cmd , " event " , & eventName ) < 0 )
return false ;
if ( ! eventName ) {
vshError ( ctl , " %s " , _ ( " either --list or --event <type> is required " ) ) ;
return false ;
}
for ( event = 0 ; event < VIR_SECRET_EVENT_ID_LAST ; event + + )
2018-05-23 09:32:39 +03:00
if ( STREQ ( eventName , virshSecretEventCallbacks [ event ] . name ) )
2016-12-22 19:39:43 +03:00
break ;
if ( event = = VIR_SECRET_EVENT_ID_LAST ) {
vshError ( ctl , _ ( " unknown event type %s " ) , eventName ) ;
return false ;
}
data . ctl = ctl ;
data . loop = vshCommandOptBool ( cmd , " loop " ) ;
data . timestamp = vshCommandOptBool ( cmd , " timestamp " ) ;
data . count = 0 ;
2018-05-23 09:32:39 +03:00
data . cb = & virshSecretEventCallbacks [ event ] ;
2016-12-22 19:39:43 +03:00
if ( vshCommandOptTimeoutToMs ( ctl , cmd , & timeout ) < 0 )
return false ;
if ( vshCommandOptBool ( cmd , " secret " ) )
secret = virshCommandOptSecret ( ctl , cmd , NULL ) ;
if ( vshEventStart ( ctl , timeout ) < 0 )
goto cleanup ;
if ( ( eventId = virConnectSecretEventRegisterAny ( priv - > conn , secret , event ,
data . cb - > cb ,
& data , NULL ) ) < 0 )
goto cleanup ;
switch ( vshEventWait ( ctl ) ) {
case VSH_EVENT_INTERRUPT :
vshPrint ( ctl , " %s " , _ ( " event loop interrupted \n " ) ) ;
break ;
case VSH_EVENT_TIMEOUT :
vshPrint ( ctl , " %s " , _ ( " event loop timed out \n " ) ) ;
break ;
case VSH_EVENT_DONE :
break ;
default :
goto cleanup ;
}
vshPrint ( ctl , _ ( " events received: %d \n " ) , data . count ) ;
if ( data . count )
ret = true ;
cleanup :
vshEventCleanup ( ctl ) ;
if ( eventId > = 0 & &
virConnectSecretEventDeregisterAny ( priv - > conn , eventId ) < 0 )
ret = false ;
2020-01-24 17:24:49 +03:00
virshSecretFree ( secret ) ;
2016-12-22 19:39:43 +03:00
return ret ;
}
2012-08-21 03:14:37 +04:00
const vshCmdDef secretCmds [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " secret-define " ,
. handler = cmdSecretDefine ,
. opts = opts_secret_define ,
. info = info_secret_define ,
. flags = 0
} ,
{ . name = " secret-dumpxml " ,
. handler = cmdSecretDumpXML ,
. opts = opts_secret_dumpxml ,
. info = info_secret_dumpxml ,
. flags = 0
} ,
2016-12-22 19:39:43 +03:00
{ . name = " secret-event " ,
. handler = cmdSecretEvent ,
. opts = opts_secret_event ,
. info = info_secret_event ,
. flags = 0
} ,
2013-02-07 19:25:10 +04:00
{ . name = " secret-get-value " ,
. handler = cmdSecretGetValue ,
. opts = opts_secret_get_value ,
. info = info_secret_get_value ,
. flags = 0
} ,
{ . name = " secret-list " ,
. handler = cmdSecretList ,
. opts = opts_secret_list ,
. info = info_secret_list ,
. flags = 0
} ,
{ . name = " secret-set-value " ,
. handler = cmdSecretSetValue ,
. opts = opts_secret_set_value ,
. info = info_secret_set_value ,
. flags = 0
} ,
{ . name = " secret-undefine " ,
. handler = cmdSecretUndefine ,
. opts = opts_secret_undefine ,
. info = info_secret_undefine ,
. flags = 0
} ,
{ . name = NULL }
2012-07-23 11:19:04 +04:00
} ;