mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-07 01:13:49 +00:00
virsh: Split cmds to manage secret from virsh.c
Commands to manage secret are moved from virsh.c to virsh-secret.c, with a few helpers for secret command use. * virsh.c: Remove secret commands and a few helpers. (vshCommandOptSecret, and vshCommandOptSecretBy) * virsh-secret.c: New file, filled with secret commands and its helpers. * po/POTFILES.in: Add virsh-secret.c * cfg.mk: Skip to check config.h including for virsh-secret.c
This commit is contained in:
parent
e9d10055df
commit
d7acdcf093
2
cfg.mk
2
cfg.mk
@ -773,7 +773,7 @@ exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
|
|||||||
|
|
||||||
exclude_file_name_regexp--sc_prohibit_return_as_function = \.py$$
|
exclude_file_name_regexp--sc_prohibit_return_as_function = \.py$$
|
||||||
|
|
||||||
_virsh_includes=(edit|domain-monitor|domain|volume|pool|network|interface|nwfilter)
|
_virsh_includes=(edit|domain-monitor|domain|volume|pool|network|interface|nwfilter|secret)
|
||||||
exclude_file_name_regexp--sc_require_config_h = ^(examples/|tools/virsh-$(_virsh_includes)\.c$$)
|
exclude_file_name_regexp--sc_require_config_h = ^(examples/|tools/virsh-$(_virsh_includes)\.c$$)
|
||||||
|
|
||||||
exclude_file_name_regexp--sc_require_config_h_first = ^(examples/|tools/virsh-$(_virsh_includes)\.c$$)
|
exclude_file_name_regexp--sc_require_config_h_first = ^(examples/|tools/virsh-$(_virsh_includes)\.c$$)
|
||||||
|
@ -184,6 +184,7 @@ tools/virsh-interface.c
|
|||||||
tools/virsh-network.c
|
tools/virsh-network.c
|
||||||
tools/virsh-nwfilter.c
|
tools/virsh-nwfilter.c
|
||||||
tools/virsh-pool.c
|
tools/virsh-pool.c
|
||||||
|
tools/virsh-secret.c
|
||||||
tools/virsh-volume.c
|
tools/virsh-volume.c
|
||||||
tools/virt-host-validate-common.c
|
tools/virt-host-validate-common.c
|
||||||
tools/virt-host-validate-lxc.c
|
tools/virt-host-validate-lxc.c
|
||||||
|
358
tools/virsh-secret.c
Normal file
358
tools/virsh-secret.c
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
340
tools/virsh.c
340
tools/virsh.c
@ -338,9 +338,6 @@ static virDomainPtr vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd,
|
|||||||
#define vshCommandOptDomain(_ctl, _cmd, _name) \
|
#define vshCommandOptDomain(_ctl, _cmd, _name) \
|
||||||
vshCommandOptDomainBy(_ctl, _cmd, _name, VSH_BYID|VSH_BYUUID|VSH_BYNAME)
|
vshCommandOptDomainBy(_ctl, _cmd, _name, VSH_BYID|VSH_BYUUID|VSH_BYNAME)
|
||||||
|
|
||||||
static virSecretPtr vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd,
|
|
||||||
const char **name);
|
|
||||||
|
|
||||||
static void vshPrintExtra(vshControl *ctl, const char *format, ...)
|
static void vshPrintExtra(vshControl *ctl, const char *format, ...)
|
||||||
ATTRIBUTE_FMT_PRINTF(2, 3);
|
ATTRIBUTE_FMT_PRINTF(2, 3);
|
||||||
static void vshDebug(vshControl *ctl, int level, const char *format, ...)
|
static void vshDebug(vshControl *ctl, int level, const char *format, ...)
|
||||||
@ -1340,314 +1337,6 @@ cmdNodeDeviceDestroy(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* "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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "version" command
|
* "version" command
|
||||||
*/
|
*/
|
||||||
@ -4880,33 +4569,6 @@ vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd,
|
|||||||
return dom;
|
return dom;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Executes command(s) and returns return code from last command
|
* Executes command(s) and returns return code from last command
|
||||||
*/
|
*/
|
||||||
@ -6493,6 +6155,8 @@ static const vshCmdDef nwfilterCmds[] = {
|
|||||||
{NULL, NULL, NULL, NULL, 0}
|
{NULL, NULL, NULL, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "virsh-secret.c"
|
||||||
|
|
||||||
static const vshCmdDef secretCmds[] = {
|
static const vshCmdDef secretCmds[] = {
|
||||||
{"secret-define", cmdSecretDefine, opts_secret_define,
|
{"secret-define", cmdSecretDefine, opts_secret_define,
|
||||||
info_secret_define, 0},
|
info_secret_define, 0},
|
||||||
|
Loading…
Reference in New Issue
Block a user