2012-07-23 10:18:51 +04:00
/*
* virsh - secret . c : Commands to manage secret
*
* Copyright ( C ) 2005 , 2007 - 2012 Red Hat , Inc .
*
* 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
* License along with this library ; If not , see
* < http : //www.gnu.org/licenses/>.
*
* Daniel Veillard < veillard @ redhat . com >
* Karel Zak < kzak @ redhat . com >
* Daniel P . Berrange < berrange @ redhat . com >
*
*/
static virSecretPtr
vshCommandOptSecret ( vshControl * ctl , const vshCmd * cmd , const char * * name )
{
virSecretPtr secret = NULL ;
const char * n = NULL ;
const char * optname = " secret " ;
if ( ! cmd_has_option ( ctl , cmd , optname ) )
return NULL ;
if ( vshCommandOptString ( cmd , optname , & n ) < = 0 )
return NULL ;
vshDebug ( ctl , VSH_ERR_DEBUG ,
" %s: found option <%s>: %s \n " , cmd - > def - > name , optname , n ) ;
if ( name ! = NULL )
* name = n ;
secret = virSecretLookupByUUIDString ( ctl - > conn , n ) ;
if ( secret = = NULL )
vshError ( ctl , _ ( " failed to get secret '%s' " ) , n ) ;
return secret ;
}
/*
* " secret-define " command
*/
static const vshCmdInfo info_secret_define [ ] = {
{ " help " , N_ ( " define or modify a secret from an XML file " ) } ,
{ " desc " , N_ ( " Define or modify a secret. " ) } ,
{ NULL , NULL }
} ;
static const vshCmdOptDef opts_secret_define [ ] = {
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , N_ ( " file containing secret attributes in XML " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static bool
cmdSecretDefine ( vshControl * ctl , const vshCmd * cmd )
{
const char * from = NULL ;
char * buffer ;
virSecretPtr res ;
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn ) )
return false ;
if ( vshCommandOptString ( cmd , " file " , & from ) < = 0 )
return false ;
if ( virFileReadAll ( from , VIRSH_MAX_XML_FILE , & buffer ) < 0 )
return false ;
res = virSecretDefineXML ( ctl - > conn , buffer , 0 ) ;
VIR_FREE ( buffer ) ;
if ( res = = NULL ) {
vshError ( ctl , _ ( " Failed to set attributes from %s " ) , from ) ;
return false ;
}
if ( virSecretGetUUIDString ( res , & ( uuid [ 0 ] ) ) < 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to get UUID of created secret " ) ) ;
virSecretFree ( res ) ;
return false ;
}
vshPrint ( ctl , _ ( " Secret %s created \n " ) , uuid ) ;
virSecretFree ( res ) ;
return true ;
}
/*
* " secret-dumpxml " command
*/
static const vshCmdInfo info_secret_dumpxml [ ] = {
{ " help " , N_ ( " secret attributes in XML " ) } ,
{ " desc " , N_ ( " Output attributes of a secret as an XML dump to stdout. " ) } ,
{ NULL , NULL }
} ;
static const vshCmdOptDef opts_secret_dumpxml [ ] = {
{ " secret " , VSH_OT_DATA , VSH_OFLAG_REQ , N_ ( " secret UUID " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static bool
cmdSecretDumpXML ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret ;
bool ret = false ;
char * xml ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn ) )
return false ;
secret = vshCommandOptSecret ( ctl , cmd , NULL ) ;
if ( secret = = NULL )
return false ;
xml = virSecretGetXMLDesc ( secret , 0 ) ;
if ( xml = = NULL )
goto cleanup ;
vshPrint ( ctl , " %s " , xml ) ;
VIR_FREE ( xml ) ;
ret = true ;
cleanup :
virSecretFree ( secret ) ;
return ret ;
}
/*
* " secret-set-value " command
*/
static const vshCmdInfo info_secret_set_value [ ] = {
{ " help " , N_ ( " set a secret value " ) } ,
{ " desc " , N_ ( " Set a secret value. " ) } ,
{ NULL , NULL }
} ;
static const vshCmdOptDef opts_secret_set_value [ ] = {
{ " secret " , VSH_OT_DATA , VSH_OFLAG_REQ , N_ ( " secret UUID " ) } ,
{ " base64 " , VSH_OT_DATA , VSH_OFLAG_REQ , N_ ( " base64-encoded secret value " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static bool
cmdSecretSetValue ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret ;
size_t value_size ;
const char * base64 = NULL ;
char * value ;
int res ;
bool ret = false ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn ) )
return false ;
secret = vshCommandOptSecret ( ctl , cmd , NULL ) ;
if ( secret = = NULL )
return false ;
if ( vshCommandOptString ( cmd , " base64 " , & base64 ) < = 0 )
goto cleanup ;
if ( ! base64_decode_alloc ( base64 , strlen ( base64 ) , & value , & value_size ) ) {
vshError ( ctl , " %s " , _ ( " Invalid base64 data " ) ) ;
goto cleanup ;
}
if ( value = = NULL ) {
vshError ( ctl , " %s " , _ ( " Failed to allocate memory " ) ) ;
return false ;
}
res = virSecretSetValue ( secret , ( unsigned char * ) value , value_size , 0 ) ;
memset ( value , 0 , value_size ) ;
VIR_FREE ( value ) ;
if ( res ! = 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to set secret value " ) ) ;
goto cleanup ;
}
vshPrint ( ctl , " %s " , _ ( " Secret value set \n " ) ) ;
ret = true ;
cleanup :
virSecretFree ( secret ) ;
return ret ;
}
/*
* " secret-get-value " command
*/
static const vshCmdInfo info_secret_get_value [ ] = {
{ " help " , N_ ( " Output a secret value " ) } ,
{ " desc " , N_ ( " Output a secret value to stdout. " ) } ,
{ NULL , NULL }
} ;
static const vshCmdOptDef opts_secret_get_value [ ] = {
{ " secret " , VSH_OT_DATA , VSH_OFLAG_REQ , N_ ( " secret UUID " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static bool
cmdSecretGetValue ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret ;
char * base64 ;
unsigned char * value ;
size_t value_size ;
bool ret = false ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn ) )
return false ;
secret = vshCommandOptSecret ( ctl , cmd , NULL ) ;
if ( secret = = NULL )
return false ;
value = virSecretGetValue ( secret , & value_size , 0 ) ;
if ( value = = NULL )
goto cleanup ;
base64_encode_alloc ( ( char * ) value , value_size , & base64 ) ;
memset ( value , 0 , value_size ) ;
VIR_FREE ( value ) ;
if ( base64 = = NULL ) {
vshError ( ctl , " %s " , _ ( " Failed to allocate memory " ) ) ;
goto cleanup ;
}
vshPrint ( ctl , " %s " , base64 ) ;
memset ( base64 , 0 , strlen ( base64 ) ) ;
VIR_FREE ( base64 ) ;
ret = true ;
cleanup :
virSecretFree ( secret ) ;
return ret ;
}
/*
* " secret-undefine " command
*/
static const vshCmdInfo info_secret_undefine [ ] = {
{ " help " , N_ ( " undefine a secret " ) } ,
{ " desc " , N_ ( " Undefine a secret. " ) } ,
{ NULL , NULL }
} ;
static const vshCmdOptDef opts_secret_undefine [ ] = {
{ " secret " , VSH_OT_DATA , VSH_OFLAG_REQ , N_ ( " secret UUID " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static bool
cmdSecretUndefine ( vshControl * ctl , const vshCmd * cmd )
{
virSecretPtr secret ;
bool ret = false ;
const char * uuid ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn ) )
return false ;
secret = vshCommandOptSecret ( ctl , cmd , & uuid ) ;
if ( secret = = NULL )
return false ;
if ( virSecretUndefine ( secret ) < 0 ) {
vshError ( ctl , _ ( " Failed to delete secret %s " ) , uuid ) ;
goto cleanup ;
}
vshPrint ( ctl , _ ( " Secret %s deleted \n " ) , uuid ) ;
ret = true ;
cleanup :
virSecretFree ( secret ) ;
return ret ;
}
/*
* " secret-list " command
*/
static const vshCmdInfo info_secret_list [ ] = {
{ " help " , N_ ( " list secrets " ) } ,
{ " desc " , N_ ( " Returns a list of secrets " ) } ,
{ NULL , NULL }
} ;
static bool
cmdSecretList ( vshControl * ctl , const vshCmd * cmd ATTRIBUTE_UNUSED )
{
int maxuuids = 0 , i ;
char * * uuids = NULL ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn ) )
return false ;
maxuuids = virConnectNumOfSecrets ( ctl - > conn ) ;
if ( maxuuids < 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to list secrets " ) ) ;
return false ;
}
uuids = vshMalloc ( ctl , sizeof ( * uuids ) * maxuuids ) ;
maxuuids = virConnectListSecrets ( ctl - > conn , uuids , maxuuids ) ;
if ( maxuuids < 0 ) {
vshError ( ctl , " %s " , _ ( " Failed to list secrets " ) ) ;
VIR_FREE ( uuids ) ;
return false ;
}
qsort ( uuids , maxuuids , sizeof ( char * ) , vshNameSorter ) ;
vshPrintExtra ( ctl , " %-36s %s \n " , _ ( " UUID " ) , _ ( " Usage " ) ) ;
vshPrintExtra ( ctl , " ----------------------------------------------------------- \n " ) ;
for ( i = 0 ; i < maxuuids ; i + + ) {
virSecretPtr sec = virSecretLookupByUUIDString ( ctl - > conn , uuids [ i ] ) ;
const char * usageType = NULL ;
if ( ! sec ) {
VIR_FREE ( uuids [ i ] ) ;
continue ;
}
switch ( virSecretGetUsageType ( sec ) ) {
case VIR_SECRET_USAGE_TYPE_VOLUME :
usageType = _ ( " Volume " ) ;
break ;
}
if ( usageType ) {
vshPrint ( ctl , " %-36s %s %s \n " ,
uuids [ i ] , usageType ,
virSecretGetUsageID ( sec ) ) ;
} else {
vshPrint ( ctl , " %-36s %s \n " ,
uuids [ i ] , _ ( " Unused " ) ) ;
}
virSecretFree ( sec ) ;
VIR_FREE ( uuids [ i ] ) ;
}
VIR_FREE ( uuids ) ;
return true ;
}
2012-07-23 11:19:04 +04:00
static const vshCmdDef secretCmds [ ] = {
{ " secret-define " , cmdSecretDefine , opts_secret_define ,
info_secret_define , 0 } ,
{ " secret-dumpxml " , cmdSecretDumpXML , opts_secret_dumpxml ,
info_secret_dumpxml , 0 } ,
{ " secret-get-value " , cmdSecretGetValue , opts_secret_get_value ,
info_secret_get_value , 0 } ,
{ " secret-list " , cmdSecretList , NULL , info_secret_list , 0 } ,
{ " secret-set-value " , cmdSecretSetValue , opts_secret_set_value ,
info_secret_set_value , 0 } ,
{ " secret-undefine " , cmdSecretUndefine , opts_secret_undefine ,
info_secret_undefine , 0 } ,
{ NULL , NULL , NULL , NULL , 0 }
} ;