mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-05 04:25:19 +00:00
list: Use virConnectListAllSecrets in virsh
This introduces four new options for secret-list, to filter the returned secrets by whether it's ephemeral or not, and/or by whether it's private or not. * tools/virsh-secret.c: (New helper vshSecretSorter, vshSecretListFree, and vshCollectSecretList; Use the new API for secret-list; error out if flags are specified, because there is no way to filter the results when using old APIs (no APIs to get the properties (ephemeral, private) of a secret yet). * tools/virsh.pod: Document the 4 new options.
This commit is contained in:
parent
473ee27e6a
commit
d15d092cda
@ -290,6 +290,141 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vshSecretSorter(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vshSecretList {
|
||||||
|
virSecretPtr *secrets;
|
||||||
|
size_t nsecrets;
|
||||||
|
};
|
||||||
|
typedef struct vshSecretList *vshSecretListPtr;
|
||||||
|
|
||||||
|
static void
|
||||||
|
vshSecretListFree(vshSecretListPtr list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (list && list->nsecrets) {
|
||||||
|
for (i = 0; i < list->nsecrets; i++) {
|
||||||
|
if (list->secrets[i])
|
||||||
|
virSecretFree(list->secrets[i]);
|
||||||
|
}
|
||||||
|
VIR_FREE(list->secrets);
|
||||||
|
}
|
||||||
|
VIR_FREE(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static vshSecretListPtr
|
||||||
|
vshSecretListCollect(vshControl *ctl,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
vshSecretListPtr list = vshMalloc(ctl, sizeof(*list));
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
virSecretPtr secret;
|
||||||
|
bool success = false;
|
||||||
|
size_t deleted = 0;
|
||||||
|
int nsecrets = 0;
|
||||||
|
char **uuids = NULL;
|
||||||
|
|
||||||
|
/* try the list with flags support (0.10.2 and later) */
|
||||||
|
if ((ret = virConnectListAllSecrets(ctl->conn,
|
||||||
|
&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;
|
||||||
|
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsecrets = virConnectNumOfSecrets(ctl->conn);
|
||||||
|
if (nsecrets < 0) {
|
||||||
|
vshError(ctl, "%s", _("Failed to count secrets"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nsecrets == 0)
|
||||||
|
return list;
|
||||||
|
|
||||||
|
uuids = vshMalloc(ctl, sizeof(char *) * nsecrets);
|
||||||
|
|
||||||
|
nsecrets = virConnectListSecrets(ctl->conn, uuids, nsecrets);
|
||||||
|
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 */
|
||||||
|
for (i = 0; i < nsecrets ; i++) {
|
||||||
|
if (!(secret = virSecretLookupByUUIDString(ctl->conn, uuids[i])))
|
||||||
|
continue;
|
||||||
|
list->secrets[list->nsecrets++] = secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* truncate secrets that weren't found */
|
||||||
|
deleted = nsecrets - list->nsecrets;
|
||||||
|
|
||||||
|
finished:
|
||||||
|
/* sort the list */
|
||||||
|
if (list->secrets && list->nsecrets)
|
||||||
|
qsort(list->secrets, list->nsecrets,
|
||||||
|
sizeof(*list->secrets), vshSecretSorter);
|
||||||
|
|
||||||
|
/* truncate the list for not found secret objects */
|
||||||
|
if (deleted)
|
||||||
|
VIR_SHRINK_N(list->secrets, list->nsecrets, deleted);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for (i = 0; i < nsecrets; i++)
|
||||||
|
VIR_FREE(uuids[i]);
|
||||||
|
VIR_FREE(uuids);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
vshSecretListFree(list);
|
||||||
|
list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "secret-list" command
|
* "secret-list" command
|
||||||
*/
|
*/
|
||||||
@ -299,59 +434,71 @@ static const vshCmdInfo info_secret_list[] = {
|
|||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_secret_list[] = {
|
||||||
|
{"ephemeral", VSH_OT_BOOL, 0, N_("list ephemeral secrets")},
|
||||||
|
{"no-ephemeral", VSH_OT_BOOL, 0, N_("list non-ephemeral secrets")},
|
||||||
|
{"private", VSH_OT_BOOL, 0, N_("list private secrets")},
|
||||||
|
{"no-private", VSH_OT_BOOL, 0, N_("list non-private secrets")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int maxuuids = 0, i;
|
int i;
|
||||||
char **uuids = NULL;
|
vshSecretListPtr list = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
unsigned int flags = 0;
|
||||||
|
|
||||||
maxuuids = virConnectNumOfSecrets(ctl->conn);
|
if (vshCommandOptBool(cmd, "ephemeral"))
|
||||||
if (maxuuids < 0) {
|
flags |= VIR_CONNECT_LIST_SECRETS_EPHEMERAL;
|
||||||
vshError(ctl, "%s", _("Failed to list secrets"));
|
|
||||||
|
if (vshCommandOptBool(cmd, "no-ephemeral"))
|
||||||
|
flags |= VIR_CONNECT_LIST_SECRETS_NO_EPHEMERAL;
|
||||||
|
|
||||||
|
if (vshCommandOptBool(cmd, "private"))
|
||||||
|
flags |= VIR_CONNECT_LIST_SECRETS_PRIVATE;
|
||||||
|
|
||||||
|
if (vshCommandOptBool(cmd, "no-private"))
|
||||||
|
flags |= VIR_CONNECT_LIST_SECRETS_NO_PRIVATE;
|
||||||
|
|
||||||
|
if (!(list = vshSecretListCollect(ctl, flags)))
|
||||||
return false;
|
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, "%-36s %s\n", _("UUID"), _("Usage"));
|
||||||
vshPrintExtra(ctl, "-----------------------------------------------------------\n");
|
vshPrintExtra(ctl, "-----------------------------------------------------------\n");
|
||||||
|
|
||||||
for (i = 0; i < maxuuids; i++) {
|
for (i = 0; i < list->nsecrets; i++) {
|
||||||
virSecretPtr sec = virSecretLookupByUUIDString(ctl->conn, uuids[i]);
|
virSecretPtr sec = list->secrets[i];
|
||||||
const char *usageType = NULL;
|
const char *usageType = NULL;
|
||||||
|
|
||||||
if (!sec) {
|
|
||||||
VIR_FREE(uuids[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (virSecretGetUsageType(sec)) {
|
switch (virSecretGetUsageType(sec)) {
|
||||||
case VIR_SECRET_USAGE_TYPE_VOLUME:
|
case VIR_SECRET_USAGE_TYPE_VOLUME:
|
||||||
usageType = _("Volume");
|
usageType = _("Volume");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char uuid[VIR_UUID_STRING_BUFLEN];
|
||||||
|
if (virSecretGetUUIDString(list->secrets[i], uuid) < 0) {
|
||||||
|
vshError(ctl, "%s", _("Failed to get uuid of secret"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (usageType) {
|
if (usageType) {
|
||||||
vshPrint(ctl, "%-36s %s %s\n",
|
vshPrint(ctl, "%-36s %s %s\n",
|
||||||
uuids[i], usageType,
|
uuid, usageType,
|
||||||
virSecretGetUsageID(sec));
|
virSecretGetUsageID(sec));
|
||||||
} else {
|
} else {
|
||||||
vshPrint(ctl, "%-36s %s\n",
|
vshPrint(ctl, "%-36s %s\n",
|
||||||
uuids[i], _("Unused"));
|
uuid, _("Unused"));
|
||||||
}
|
}
|
||||||
virSecretFree(sec);
|
|
||||||
VIR_FREE(uuids[i]);
|
|
||||||
}
|
}
|
||||||
VIR_FREE(uuids);
|
|
||||||
return true;
|
ret = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
vshSecretListFree(list);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vshCmdDef secretCmds[] = {
|
const vshCmdDef secretCmds[] = {
|
||||||
@ -361,7 +508,7 @@ const vshCmdDef secretCmds[] = {
|
|||||||
info_secret_dumpxml, 0},
|
info_secret_dumpxml, 0},
|
||||||
{"secret-get-value", cmdSecretGetValue, opts_secret_get_value,
|
{"secret-get-value", cmdSecretGetValue, opts_secret_get_value,
|
||||||
info_secret_get_value, 0},
|
info_secret_get_value, 0},
|
||||||
{"secret-list", cmdSecretList, NULL, info_secret_list, 0},
|
{"secret-list", cmdSecretList, opts_secret_list, info_secret_list, 0},
|
||||||
{"secret-set-value", cmdSecretSetValue, opts_secret_set_value,
|
{"secret-set-value", cmdSecretSetValue, opts_secret_set_value,
|
||||||
info_secret_set_value, 0},
|
info_secret_set_value, 0},
|
||||||
{"secret-undefine", cmdSecretUndefine, opts_secret_undefine,
|
{"secret-undefine", cmdSecretUndefine, opts_secret_undefine,
|
||||||
|
@ -2469,9 +2469,13 @@ encoded using Base64.
|
|||||||
Delete a I<secret> (specified by its UUID), including the associated value, if
|
Delete a I<secret> (specified by its UUID), including the associated value, if
|
||||||
any.
|
any.
|
||||||
|
|
||||||
=item B<secret-list>
|
=item B<secret-list> [I<--ephemeral>] [I<--no-ephemeral>]
|
||||||
|
[I<--private>] [I<--no-private>]
|
||||||
|
|
||||||
Output a list of UUIDs of known secrets to stdout.
|
Returns the list of secrets. You may also want to filter the returned secrets
|
||||||
|
by I<--ephemeral> to list the ephemeral ones, I<--no-ephemeral> to list the
|
||||||
|
non-ephemeral ones, I<--private> to list the private ones, and
|
||||||
|
I<--no-private> to list the non-private ones.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user