storage_pool: Rework chap XML to mimic ceph

The existing 'chap' XML logic was never used - just defined.  Rather than
try to insert a square peg into a round hole, blow it up and rewrite the
logic to follow the 'ceph' format.

Remove the former "chap.login" and "chap.passwd" fields and replace
with "chap.username" and "chap.secret" in _virStoragePoolAuthChap.
Adjust the virStoragePoolDefParseAuthChap() to process.

Change the rng file to describe the new layout

Update the formatstorage.html to describe the usage of the secret element
to mention that the secret type "iscsi" and "ceph" can be used
to storage pool too.

Update the formatsecret.html to include a reference to the storage pool

Update tests to handle the changes from 'login' and 'passwd' to 'username'
and '<secret>' format
This commit is contained in:
John Ferlan 2013-07-13 14:29:55 -04:00
parent 092ca9689a
commit eb0d79c64b
10 changed files with 87 additions and 46 deletions

View File

@ -64,8 +64,9 @@
a single <code>name</code> element that specifies a usage name a single <code>name</code> element that specifies a usage name
for the secret. The Ceph secret can then be used by UUID or by for the secret. The Ceph secret can then be used by UUID or by
this usage name via the <code>&lt;auth&gt;</code> element of this usage name via the <code>&lt;auth&gt;</code> element of
a <a href="formatdomain.html#elementsDisks">disk a <a href="formatdomain.html#elementsDisks">disk device</a> or
device</a>. <span class="since">Since 0.9.7</span>. a <a href="formatstorage.html">storage pool (rbd)</a>.
<span class="since">Since 0.9.7</span>.
</p> </p>
<h3>Usage type "iscsi"</h3> <h3>Usage type "iscsi"</h3>
@ -76,8 +77,9 @@
a single <code>target</code> element that specifies a usage name a single <code>target</code> element that specifies a usage name
for the secret. The iSCSI secret can then be used by UUID or by for the secret. The iSCSI secret can then be used by UUID or by
this usage name via the <code>&lt;auth&gt;</code> element of this usage name via the <code>&lt;auth&gt;</code> element of
a <a href="formatdomain.html#elementsDisks">disk a <a href="formatdomain.html#elementsDisks">disk device</a> or
device</a>. <span class="since">Since 1.0.4</span>. a <a href="formatstorage.html">storage pool (iscsi)</a>.
<span class="since">Since 1.0.4</span>.
</p> </p>
<h2><a name="example">Example</a></h2> <h2><a name="example">Example</a></h2>

View File

@ -72,6 +72,9 @@
&lt;source&gt; &lt;source&gt;
&lt;host name="iscsi.example.com"/&gt; &lt;host name="iscsi.example.com"/&gt;
&lt;device path="demo-target"/&gt; &lt;device path="demo-target"/&gt;
&lt;auth type='chap' username='myname'&gt;
&lt;secret type='iscsi' usage='mycluster_myname'/&gt;
&lt;/auth&gt;
&lt;vendor name="Acme"/&gt; &lt;vendor name="Acme"/&gt;
&lt;product name="model"/&gt; &lt;product name="model"/&gt;
&lt;/source&gt; &lt;/source&gt;
@ -79,7 +82,6 @@
<pre> <pre>
... ...
&lt;source&gt;
&lt;source&gt; &lt;source&gt;
&lt;adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/&gt; &lt;adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/&gt;
&lt;/source&gt; &lt;/source&gt;
@ -123,6 +125,27 @@
which is the hostname or IP address of the server. May optionally which is the hostname or IP address of the server. May optionally
contain a <code>port</code> attribute for the protocol specific contain a <code>port</code> attribute for the protocol specific
port number. <span class="since">Since 0.4.1</span></dd> port number. <span class="since">Since 0.4.1</span></dd>
<dt><code>auth</code></dt>
<dd>If present, the <code>auth</code> element provides the
authentication credentials needed to access the source by the
setting of the <code>type</code> attribute. The <code>type</code>
must be either "chap" or "ceph". Additionally a mandatory attribute
<code>username</code> identifies the username to use during
authentication as well as a sub-element <code>secret</code> with
a 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 manages the password. The secret element
<code>type</code> must be either "ceph" or "iscsi". Use "ceph" for
Ceph RBD (Rados Block Device) network sources and use "iscsi" for CHAP
(Challenge-Handshake Authentication Protocol) iSCSI targets.
The <code>secret</code> element requires either a <code>uuid</code>
attribute with the UUID of the secret object or a <code>usage</code>
attribute matching the key that was specified in the
secret object. <span class="since">Since 0.9.7 for "ceph" and
1.1.1 for "chap"</span>
</dd>
<dt><code>name</code></dt> <dt><code>name</code></dt>
<dd>Provides the source for pools backed by storage from a <dd>Provides the source for pools backed by storage from a
named element (e.g., a logical volume group name). named element (e.g., a logical volume group name).

View File

@ -286,22 +286,10 @@
<value>ceph</value> <value>ceph</value>
</choice> </choice>
</attribute> </attribute>
<choice>
<attribute name='login'>
<text/>
</attribute>
<attribute name='username'> <attribute name='username'>
<text/> <text/>
</attribute> </attribute>
</choice>
<optional>
<attribute name='passwd'>
<text/>
</attribute>
</optional>
<optional>
<ref name='sourceinfoauthsecret'/> <ref name='sourceinfoauthsecret'/>
</optional>
</element> </element>
</define> </define>

View File

@ -365,8 +365,8 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source)
VIR_FREE(source->product); VIR_FREE(source->product);
if (source->authType == VIR_STORAGE_POOL_AUTH_CHAP) { if (source->authType == VIR_STORAGE_POOL_AUTH_CHAP) {
VIR_FREE(source->auth.chap.login); VIR_FREE(source->auth.chap.username);
VIR_FREE(source->auth.chap.passwd); VIR_FREE(source->auth.chap.secret.usage);
} }
if (source->authType == VIR_STORAGE_POOL_AUTH_CEPHX) { if (source->authType == VIR_STORAGE_POOL_AUTH_CEPHX) {
@ -461,21 +461,44 @@ static int
virStoragePoolDefParseAuthChap(xmlXPathContextPtr ctxt, virStoragePoolDefParseAuthChap(xmlXPathContextPtr ctxt,
virStoragePoolAuthChapPtr auth) virStoragePoolAuthChapPtr auth)
{ {
auth->login = virXPathString("string(./auth/@login)", ctxt); char *uuid = NULL;
if (auth->login == NULL) { int ret = -1;
auth->username = virXPathString("string(./auth/@username)", ctxt);
if (auth->username == NULL) {
virReportError(VIR_ERR_XML_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing auth login attribute")); _("missing auth username attribute"));
return -1; return -1;
} }
auth->passwd = virXPathString("string(./auth/@passwd)", ctxt); uuid = virXPathString("string(./auth/secret/@uuid)", ctxt);
if (auth->passwd == NULL) { auth->secret.usage = virXPathString("string(./auth/secret/@usage)", ctxt);
if (uuid == NULL && auth->secret.usage == NULL) {
virReportError(VIR_ERR_XML_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing auth passwd attribute")); _("missing auth secret uuid or usage attribute"));
return -1; return -1;
} }
return 0; if (uuid != NULL) {
if (auth->secret.usage != NULL) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("either auth secret uuid or usage expected"));
goto cleanup;
}
if (virUUIDParse(uuid, auth->secret.uuid) < 0) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("invalid auth secret uuid"));
goto cleanup;
}
auth->secret.uuidUsable = true;
} else {
auth->secret.uuidUsable = false;
}
ret = 0;
cleanup:
VIR_FREE(uuid);
return ret;
} }
static int static int
@ -1134,16 +1157,13 @@ virStoragePoolSourceFormat(virBufferPtr buf,
virBufferAsprintf(buf," <format type='%s'/>\n", format); virBufferAsprintf(buf," <format type='%s'/>\n", format);
} }
if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP) if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP ||
virBufferAsprintf(buf," <auth type='%s' login='%s' passwd='%s'/>\n", src->authType == VIR_STORAGE_POOL_AUTH_CEPHX) {
virBufferAsprintf(buf," <auth type='%s' username='%s'>\n",
virStoragePoolAuthTypeTypeToString(src->authType), virStoragePoolAuthTypeTypeToString(src->authType),
src->auth.chap.login, (src->authType == VIR_STORAGE_POOL_AUTH_CHAP ?
src->auth.chap.passwd); src->auth.chap.username :
src->auth.cephx.username));
if (src->authType == VIR_STORAGE_POOL_AUTH_CEPHX) {
virBufferAsprintf(buf," <auth username='%s' type='%s'>\n",
src->auth.cephx.username,
virStoragePoolAuthTypeTypeToString(src->authType));
virBufferAddLit(buf," <secret"); virBufferAddLit(buf," <secret");
if (src->auth.cephx.secret.uuidUsable) { if (src->auth.cephx.secret.uuidUsable) {

View File

@ -162,8 +162,8 @@ struct _virStoragePoolAuthSecret {
typedef struct _virStoragePoolAuthChap virStoragePoolAuthChap; typedef struct _virStoragePoolAuthChap virStoragePoolAuthChap;
typedef virStoragePoolAuthChap *virStoragePoolAuthChapPtr; typedef virStoragePoolAuthChap *virStoragePoolAuthChapPtr;
struct _virStoragePoolAuthChap { struct _virStoragePoolAuthChap {
char *login; char *username;
char *passwd; virStoragePoolAuthSecret secret;
}; };
typedef struct _virStoragePoolAuthCephx virStoragePoolAuthCephx; typedef struct _virStoragePoolAuthCephx virStoragePoolAuthCephx;

View File

@ -4,7 +4,9 @@
<source> <source>
<host name="iscsi.example.com"/> <host name="iscsi.example.com"/>
<device path="demo-target"/> <device path="demo-target"/>
<auth type='chap' login='foobar' passwd='frobbar'/> <auth type='chap' username='admin'>
<secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
</auth>
</source> </source>
<target> <target>
<path>/dev/disk/by-path</path> <path>/dev/disk/by-path</path>

View File

@ -4,7 +4,9 @@
<source> <source>
<host name="iscsi.example.com"/> <host name="iscsi.example.com"/>
<device path="demo-target"/> <device path="demo-target"/>
<auth type='chap' login='foobar' passwd='frobbar'/> <auth type='chap' username='admin'>
<secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
</auth>
<vendor name='test-vendor'/> <vendor name='test-vendor'/>
<product name='test-product'/> <product name='test-product'/>
</source> </source>

View File

@ -7,7 +7,9 @@
<source> <source>
<host name='iscsi.example.com'/> <host name='iscsi.example.com'/>
<device path='demo-target'/> <device path='demo-target'/>
<auth type='chap' login='foobar' passwd='frobbar'/> <auth type='chap' username='admin'>
<secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
</auth>
</source> </source>
<target> <target>
<path>/dev/disk/by-path</path> <path>/dev/disk/by-path</path>

View File

@ -7,7 +7,9 @@
<source> <source>
<host name='iscsi.example.com'/> <host name='iscsi.example.com'/>
<device path='demo-target'/> <device path='demo-target'/>
<auth type='chap' login='foobar' passwd='frobbar'/> <auth type='chap' username='admin'>
<secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
</auth>
<vendor name='test-vendor'/> <vendor name='test-vendor'/>
<product name='test-product'/> <product name='test-product'/>
</source> </source>

View File

@ -8,7 +8,7 @@
<name>rbd</name> <name>rbd</name>
<host name='localhost' port='6789'/> <host name='localhost' port='6789'/>
<host name='localhost' port='6790'/> <host name='localhost' port='6790'/>
<auth username='admin' type='ceph'> <auth type='ceph' username='admin'>
<secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/> <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
</auth> </auth>
</source> </source>