mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
storage: add auth to virDomainDiskDef
Add additional fields to let you specify the how to authenticate with a disk. The secret to use may be referenced by a usage string or a UUID, i.e.: <auth username='myuser'> <secret type='ceph' usage='secretname'/> </auth> or <auth username='myuser'> <secret type='ceph' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </auth> Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
This commit is contained in:
parent
536d1f8746
commit
5bd6271f59
1
AUTHORS
1
AUTHORS
@ -200,6 +200,7 @@ Patches have also been contributed by:
|
|||||||
Sage Weil <sage@newdream.net>
|
Sage Weil <sage@newdream.net>
|
||||||
David L Stevens <dlstevens@us.ibm.com>
|
David L Stevens <dlstevens@us.ibm.com>
|
||||||
Tyler Coumbes <coumbes@gmail.com>
|
Tyler Coumbes <coumbes@gmail.com>
|
||||||
|
Josh Durgin <josh.durgin@dreamhost.com>
|
||||||
|
|
||||||
[....send patches to get your name here....]
|
[....send patches to get your name here....]
|
||||||
|
|
||||||
|
@ -913,6 +913,16 @@
|
|||||||
<transient/>
|
<transient/>
|
||||||
<address type='drive' controller='0' bus='1' unit='0'/>
|
<address type='drive' controller='0' bus='1' unit='0'/>
|
||||||
</disk>
|
</disk>
|
||||||
|
<disk type='network'>
|
||||||
|
<driver name="qemu" type="raw"/>
|
||||||
|
<source protocol="rbd" name="image_name2">
|
||||||
|
<host name="hostname" port="7000"/>
|
||||||
|
</source>
|
||||||
|
<target dev="hdd" bus="ide"/>
|
||||||
|
<auth username='myuser'>
|
||||||
|
<secret type='ceph' usage='mypassid'/>
|
||||||
|
</auth>
|
||||||
|
</disk>
|
||||||
<disk type='block' device='cdrom'>
|
<disk type='block' device='cdrom'>
|
||||||
<driver name='qemu' type='raw'/>
|
<driver name='qemu' type='raw'/>
|
||||||
<target def='hdc' bus='ide'/>
|
<target def='hdc' bus='ide'/>
|
||||||
@ -1160,7 +1170,24 @@
|
|||||||
"drive" controller, additional attributes
|
"drive" controller, additional attributes
|
||||||
<code>controller</code>, <code>bus</code>,
|
<code>controller</code>, <code>bus</code>,
|
||||||
and <code>unit</code> are available, each defaulting to 0.
|
and <code>unit</code> are available, each defaulting to 0.
|
||||||
|
</dd>
|
||||||
|
<dt><code>auth</code></dt>
|
||||||
|
<dd>If present, the <code>auth</code> element provides the
|
||||||
|
authentication credentials needed to access the source. It
|
||||||
|
includes a mandatory attribute <code>username</code>, which
|
||||||
|
identifies the username to use during authentication, as well
|
||||||
|
as a sub-element <code>secret</code> with mandatory
|
||||||
|
attribute <code>type</code>, to tie back to
|
||||||
|
a <a href="formatsecret.html">libvirt secret object</a> that
|
||||||
|
holds the actual password or other credentials (the domain XML
|
||||||
|
intentionally does not expose the password, only the reference
|
||||||
|
to the object that does manage the password). For now, the
|
||||||
|
only known secret <code>type</code> is "ceph", for Ceph RBD
|
||||||
|
network sources, and requires either an
|
||||||
|
attribute <code>uuid</code> with the UUID of the Ceph secret
|
||||||
|
object, or an attribute <code>usage</code> with the name
|
||||||
|
associated with the Ceph secret
|
||||||
|
object. <span class="since">libvirt 0.9.7</span>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
@ -602,6 +602,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="driver"/>
|
<ref name="driver"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="diskAuth"/>
|
||||||
|
</optional>
|
||||||
<ref name="target"/>
|
<ref name="target"/>
|
||||||
<optional>
|
<optional>
|
||||||
<ref name="deviceBoot"/>
|
<ref name="deviceBoot"/>
|
||||||
@ -2535,6 +2538,32 @@
|
|||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
<define name="diskAuth">
|
||||||
|
<element name="auth">
|
||||||
|
<attribute name="username">
|
||||||
|
<ref name="genericName"/>
|
||||||
|
</attribute>
|
||||||
|
<ref name="diskAuthSecret"/>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
|
|
||||||
|
<define name='diskAuthSecret'>
|
||||||
|
<element name='secret'>
|
||||||
|
<attribute name='type'>
|
||||||
|
<choice>
|
||||||
|
<value>ceph</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
<choice>
|
||||||
|
<attribute name='uuid'>
|
||||||
|
<ref name="UUID"/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="usage">
|
||||||
|
<ref name="genericName"/>
|
||||||
|
</attribute>
|
||||||
|
</choice>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Optional hypervisor extensions in their own namespace:
|
Optional hypervisor extensions in their own namespace:
|
||||||
|
@ -1475,6 +1475,7 @@ libvirt_lxc_SOURCES = \
|
|||||||
$(NODE_INFO_SOURCES) \
|
$(NODE_INFO_SOURCES) \
|
||||||
$(ENCRYPTION_CONF_SOURCES) \
|
$(ENCRYPTION_CONF_SOURCES) \
|
||||||
$(DOMAIN_CONF_SOURCES) \
|
$(DOMAIN_CONF_SOURCES) \
|
||||||
|
$(SECRET_CONF_SOURCES) \
|
||||||
$(CPU_CONF_SOURCES) \
|
$(CPU_CONF_SOURCES) \
|
||||||
$(NWFILTER_PARAM_CONF_SOURCES)
|
$(NWFILTER_PARAM_CONF_SOURCES)
|
||||||
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)
|
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "count-one-bits.h"
|
#include "count-one-bits.h"
|
||||||
|
#include "secret_conf.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||||||
|
|
||||||
@ -185,6 +186,11 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
|
|||||||
"rbd",
|
"rbd",
|
||||||
"sheepdog")
|
"sheepdog")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainDiskSecretType, VIR_DOMAIN_DISK_SECRET_TYPE_LAST,
|
||||||
|
"none",
|
||||||
|
"uuid",
|
||||||
|
"usage")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
|
VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
|
||||||
"default",
|
"default",
|
||||||
"native",
|
"native",
|
||||||
@ -788,6 +794,9 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
|
|||||||
VIR_FREE(def->dst);
|
VIR_FREE(def->dst);
|
||||||
VIR_FREE(def->driverName);
|
VIR_FREE(def->driverName);
|
||||||
VIR_FREE(def->driverType);
|
VIR_FREE(def->driverType);
|
||||||
|
VIR_FREE(def->auth.username);
|
||||||
|
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
|
||||||
|
VIR_FREE(def->auth.secret.usage);
|
||||||
virStorageEncryptionFree(def->encryption);
|
virStorageEncryptionFree(def->encryption);
|
||||||
virDomainDeviceInfoClear(&def->info);
|
virDomainDeviceInfoClear(&def->info);
|
||||||
|
|
||||||
@ -2304,7 +2313,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr def;
|
virDomainDiskDefPtr def;
|
||||||
xmlNodePtr cur, host;
|
xmlNodePtr cur, child;
|
||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
char *snapshot = NULL;
|
char *snapshot = NULL;
|
||||||
@ -2326,6 +2335,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
virStorageEncryptionPtr encryption = NULL;
|
virStorageEncryptionPtr encryption = NULL;
|
||||||
char *serial = NULL;
|
char *serial = NULL;
|
||||||
char *startupPolicy = NULL;
|
char *startupPolicy = NULL;
|
||||||
|
char *authUsername = NULL;
|
||||||
|
char *authUsage = NULL;
|
||||||
|
char *authUUID = NULL;
|
||||||
|
char *usageType = NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC(def) < 0) {
|
if (VIR_ALLOC(def) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
@ -2382,10 +2395,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
_("missing name for disk source"));
|
_("missing name for disk source"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
host = cur->children;
|
child = cur->children;
|
||||||
while (host != NULL) {
|
while (child != NULL) {
|
||||||
if (host->type == XML_ELEMENT_NODE &&
|
if (child->type == XML_ELEMENT_NODE &&
|
||||||
xmlStrEqual(host->name, BAD_CAST "host")) {
|
xmlStrEqual(child->name, BAD_CAST "host")) {
|
||||||
if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
|
if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto error;
|
goto error;
|
||||||
@ -2394,20 +2407,20 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
hosts[nhosts].port = NULL;
|
hosts[nhosts].port = NULL;
|
||||||
nhosts++;
|
nhosts++;
|
||||||
|
|
||||||
hosts[nhosts - 1].name = virXMLPropString(host, "name");
|
hosts[nhosts - 1].name = virXMLPropString(child, "name");
|
||||||
if (!hosts[nhosts - 1].name) {
|
if (!hosts[nhosts - 1].name) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("missing name for host"));
|
"%s", _("missing name for host"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
hosts[nhosts - 1].port = virXMLPropString(host, "port");
|
hosts[nhosts - 1].port = virXMLPropString(child, "port");
|
||||||
if (!hosts[nhosts - 1].port) {
|
if (!hosts[nhosts - 1].port) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("missing port for host"));
|
"%s", _("missing port for host"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
host = host->next;
|
child = child->next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2444,6 +2457,58 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
iotag = virXMLPropString(cur, "io");
|
iotag = virXMLPropString(cur, "io");
|
||||||
ioeventfd = virXMLPropString(cur, "ioeventfd");
|
ioeventfd = virXMLPropString(cur, "ioeventfd");
|
||||||
event_idx = virXMLPropString(cur, "event_idx");
|
event_idx = virXMLPropString(cur, "event_idx");
|
||||||
|
} else if (xmlStrEqual(cur->name, BAD_CAST "auth")) {
|
||||||
|
authUsername = virXMLPropString(cur, "username");
|
||||||
|
if (authUsername == NULL) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("missing username for auth"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_NONE;
|
||||||
|
child = cur->children;
|
||||||
|
while (child != NULL) {
|
||||||
|
if (child->type == XML_ELEMENT_NODE &&
|
||||||
|
xmlStrEqual(child->name, BAD_CAST "secret")) {
|
||||||
|
usageType = virXMLPropString(child, "type");
|
||||||
|
if (usageType == NULL) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("missing type for secret"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (virSecretUsageTypeTypeFromString(usageType) !=
|
||||||
|
VIR_SECRET_USAGE_TYPE_CEPH) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid secret type %s"),
|
||||||
|
usageType);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
authUUID = virXMLPropString(child, "uuid");
|
||||||
|
authUsage = virXMLPropString(child, "usage");
|
||||||
|
|
||||||
|
if (authUUID != NULL && authUsage != NULL) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("only one of uuid and usage can be specfied"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (authUUID != NULL) {
|
||||||
|
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_UUID;
|
||||||
|
if (virUUIDParse(authUUID,
|
||||||
|
def->auth.secret.uuid) < 0) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("malformed uuid %s"),
|
||||||
|
authUUID);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else if (authUsage != NULL) {
|
||||||
|
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_USAGE;
|
||||||
|
def->auth.secret.usage = authUsage;
|
||||||
|
authUsage = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
|
||||||
def->readonly = 1;
|
def->readonly = 1;
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
|
||||||
@ -2683,6 +2748,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
hosts = NULL;
|
hosts = NULL;
|
||||||
def->nhosts = nhosts;
|
def->nhosts = nhosts;
|
||||||
nhosts = 0;
|
nhosts = 0;
|
||||||
|
def->auth.username = authUsername;
|
||||||
|
authUsername = NULL;
|
||||||
def->driverName = driverName;
|
def->driverName = driverName;
|
||||||
driverName = NULL;
|
driverName = NULL;
|
||||||
def->driverType = driverType;
|
def->driverType = driverType;
|
||||||
@ -2719,6 +2786,10 @@ cleanup:
|
|||||||
VIR_FREE(hosts);
|
VIR_FREE(hosts);
|
||||||
VIR_FREE(protocol);
|
VIR_FREE(protocol);
|
||||||
VIR_FREE(device);
|
VIR_FREE(device);
|
||||||
|
VIR_FREE(authUsername);
|
||||||
|
VIR_FREE(usageType);
|
||||||
|
VIR_FREE(authUUID);
|
||||||
|
VIR_FREE(authUsage);
|
||||||
VIR_FREE(driverType);
|
VIR_FREE(driverType);
|
||||||
VIR_FREE(driverName);
|
VIR_FREE(driverName);
|
||||||
VIR_FREE(cachetag);
|
VIR_FREE(cachetag);
|
||||||
@ -9208,6 +9279,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
|||||||
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
|
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
|
||||||
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
|
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
|
||||||
|
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unexpected disk type %d"), def->type);
|
_("unexpected disk type %d"), def->type);
|
||||||
@ -9265,6 +9338,23 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
|||||||
virBufferAddLit(buf, "/>\n");
|
virBufferAddLit(buf, "/>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def->auth.username) {
|
||||||
|
virBufferEscapeString(buf, " <auth username='%s'>\n",
|
||||||
|
def->auth.username);
|
||||||
|
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) {
|
||||||
|
virUUIDFormat(def->auth.secret.uuid, uuidstr);
|
||||||
|
virBufferAsprintf(buf,
|
||||||
|
" <secret type='ceph' uuid='%s'/>\n",
|
||||||
|
uuidstr);
|
||||||
|
}
|
||||||
|
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE) {
|
||||||
|
virBufferEscapeString(buf,
|
||||||
|
" <secret type='ceph' usage='%s'/>\n",
|
||||||
|
def->auth.secret.usage);
|
||||||
|
}
|
||||||
|
virBufferAddLit(buf, " </auth>\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (def->src || def->nhosts > 0 ||
|
if (def->src || def->nhosts > 0 ||
|
||||||
def->startupPolicy) {
|
def->startupPolicy) {
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
|
@ -278,6 +278,14 @@ enum virDomainStartupPolicy {
|
|||||||
VIR_DOMAIN_STARTUP_POLICY_LAST
|
VIR_DOMAIN_STARTUP_POLICY_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum virDomainDiskSecretType {
|
||||||
|
VIR_DOMAIN_DISK_SECRET_TYPE_NONE,
|
||||||
|
VIR_DOMAIN_DISK_SECRET_TYPE_UUID,
|
||||||
|
VIR_DOMAIN_DISK_SECRET_TYPE_USAGE,
|
||||||
|
|
||||||
|
VIR_DOMAIN_DISK_SECRET_TYPE_LAST
|
||||||
|
};
|
||||||
|
|
||||||
/* Stores the virtual disk configuration */
|
/* Stores the virtual disk configuration */
|
||||||
typedef struct _virDomainDiskDef virDomainDiskDef;
|
typedef struct _virDomainDiskDef virDomainDiskDef;
|
||||||
typedef virDomainDiskDef *virDomainDiskDefPtr;
|
typedef virDomainDiskDef *virDomainDiskDefPtr;
|
||||||
@ -290,6 +298,14 @@ struct _virDomainDiskDef {
|
|||||||
int protocol;
|
int protocol;
|
||||||
int nhosts;
|
int nhosts;
|
||||||
virDomainDiskHostDefPtr hosts;
|
virDomainDiskHostDefPtr hosts;
|
||||||
|
struct {
|
||||||
|
char *username;
|
||||||
|
int secretType; /* enum virDomainDiskSecretType */
|
||||||
|
union {
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
char *usage;
|
||||||
|
} secret;
|
||||||
|
} auth;
|
||||||
char *driverName;
|
char *driverName;
|
||||||
char *driverType;
|
char *driverType;
|
||||||
char *serial;
|
char *serial;
|
||||||
@ -1881,6 +1897,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
|
|||||||
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
|
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
|
||||||
VIR_ENUM_DECL(virDomainDiskProtocol)
|
VIR_ENUM_DECL(virDomainDiskProtocol)
|
||||||
VIR_ENUM_DECL(virDomainDiskIo)
|
VIR_ENUM_DECL(virDomainDiskIo)
|
||||||
|
VIR_ENUM_DECL(virDomainDiskSecretType)
|
||||||
VIR_ENUM_DECL(virDomainDiskSnapshot)
|
VIR_ENUM_DECL(virDomainDiskSnapshot)
|
||||||
VIR_ENUM_DECL(virDomainIoEventFd)
|
VIR_ENUM_DECL(virDomainIoEventFd)
|
||||||
VIR_ENUM_DECL(virDomainVirtioEventIdx)
|
VIR_ENUM_DECL(virDomainVirtioEventIdx)
|
||||||
|
@ -930,6 +930,8 @@ virSecretDefFormat;
|
|||||||
virSecretDefFree;
|
virSecretDefFree;
|
||||||
virSecretDefParseFile;
|
virSecretDefParseFile;
|
||||||
virSecretDefParseString;
|
virSecretDefParseString;
|
||||||
|
virSecretUsageTypeTypeFromString;
|
||||||
|
virSecretUsageTypeTypeToString;
|
||||||
|
|
||||||
|
|
||||||
# security_driver.h
|
# security_driver.h
|
||||||
|
Loading…
x
Reference in New Issue
Block a user