mirror of https://gitee.com/openkylin/libvirt.git
Add info about access control checks into API reference
So that app developers / admins know what access control checks are performed for each API, this patch extends the API docs generator to include details of the ACLs for each. The gendispatch.pl script is extended so that it generates a simple XML describing ACL rules, eg. <aclinfo> ... <api name='virConnectNumOfDomains'> <check object='connect' perm='search_domains'/> <filter object='domain' perm='getattr'/> </api> <api name='virDomainAttachDeviceFlags'> <check object='domain' perm='write'/> <check object='domain' perm='save' flags='!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE'/> <check object='domain' perm='save' flags='VIR_DOMAIN_AFFECT_CONFIG'/> </api> ... </aclinfo> The newapi.xsl template loads the XML files containing the ACL rules and generates a short block of HTML for each API describing the parameter checks and return value filters (if any). Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
31d41d9268
commit
664ab2801d
|
@ -115,8 +115,11 @@
|
|||
/src/libvirt*.def
|
||||
/src/libvirt.syms
|
||||
/src/libvirt_access.syms
|
||||
/src/libvirt_access.xml
|
||||
/src/libvirt_access_lxc.syms
|
||||
/src/libvirt_access_lxc.xml
|
||||
/src/libvirt_access_qemu.syms
|
||||
/src/libvirt_access_qemu.xml
|
||||
/src/libvirt_*.stp
|
||||
/src/libvirt_*helper
|
||||
/src/libvirt_*probes.h
|
||||
|
|
|
@ -477,3 +477,17 @@ dl.variablelist > dt {
|
|||
dl.variablelist > dt:after {
|
||||
content: ": ";
|
||||
}
|
||||
|
||||
table.acl {
|
||||
margin: 1em;
|
||||
border-spacing: 0px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table.acl tr, table.acl td {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
table.acl thead {
|
||||
background: #ddd;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,69 @@
|
|||
<xsl:variable name="htmldir">html</xsl:variable>
|
||||
<xsl:variable name="href_base">../</xsl:variable>
|
||||
|
||||
<xsl:variable name="acls">
|
||||
<xsl:copy-of select="document('../src/libvirt_access.xml')/aclinfo/api"/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="qemuacls">
|
||||
<xsl:copy-of select="document('../src/libvirt_access_qemu.xml')/aclinfo/api"/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="lxcacls">
|
||||
<xsl:copy-of select="document('../src/libvirt_access_lxc.xml')/aclinfo/api"/>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:template name="aclinfo">
|
||||
<xsl:param name="api"/>
|
||||
|
||||
<xsl:if test="count(exsl:node-set($acls)/api[@name=$api]/check) > 0">
|
||||
<h5>Access control parameter checks</h5>
|
||||
<table class="acl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Object</th>
|
||||
<th>Permission</th>
|
||||
<th>Condition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<xsl:apply-templates select="exsl:node-set($acls)/api[@name=$api]/check" mode="acl"/>
|
||||
</table>
|
||||
</xsl:if>
|
||||
<xsl:if test="count(exsl:node-set($acls)/api[@name=$api]/filter) > 0">
|
||||
<h5>Access control return value filters</h5>
|
||||
<table class="acl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Object</th>
|
||||
<th>Permission</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<xsl:apply-templates select="exsl:node-set($acls)/api[@name=$api]/filter" mode="acl"/>
|
||||
</table>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="check" mode="acl">
|
||||
<tr>
|
||||
<td><xsl:value-of select="@object"/></td>
|
||||
<td><xsl:value-of select="@perm"/></td>
|
||||
<xsl:choose>
|
||||
<xsl:when test="@flags">
|
||||
<td><xsl:value-of select="@flags"/></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td>-</td>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="filter" mode="acl">
|
||||
<tr>
|
||||
<td><xsl:value-of select="@object"/></td>
|
||||
<td><xsl:value-of select="@perm"/></td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template name="navbar">
|
||||
<xsl:variable name="previous" select="preceding-sibling::file[1]"/>
|
||||
<xsl:variable name="next" select="following-sibling::file[1]"/>
|
||||
|
@ -553,6 +616,11 @@
|
|||
</xsl:if>
|
||||
</dl>
|
||||
</xsl:if>
|
||||
<div class="acl">
|
||||
<xsl:call-template name="aclinfo">
|
||||
<xsl:with-param name="api" select="$name"/>
|
||||
</xsl:call-template>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="exports" mode="toc">
|
||||
|
|
|
@ -830,6 +830,11 @@ ACCESS_DRIVER_SYM_FILES = \
|
|||
libvirt_access_qemu.syms \
|
||||
libvirt_access_lxc.syms
|
||||
|
||||
ACCESS_DRIVER_API_FILES = \
|
||||
libvirt_access.xml \
|
||||
libvirt_access_qemu.xml \
|
||||
libvirt_access_lxc.xml
|
||||
|
||||
ACCESS_DRIVER_SOURCES = \
|
||||
access/viraccessperm.h access/viraccessperm.c \
|
||||
access/viraccessmanager.h access/viraccessmanager.c \
|
||||
|
@ -1496,8 +1501,8 @@ EXTRA_DIST += $(ACCESS_DRIVER_POLKIT_SOURCES)
|
|||
endif
|
||||
|
||||
|
||||
BUILT_SOURCES += $(ACCESS_DRIVER_GENERATED)
|
||||
CLEANFILES += $(ACCESS_DRIVER_GENERATED)
|
||||
BUILT_SOURCES += $(ACCESS_DRIVER_GENERATED) $(ACCESS_DRIVER_API_FILES)
|
||||
CLEANFILES += $(ACCESS_DRIVER_GENERATED) $(ACCESS_DRIVER_API_FILES)
|
||||
|
||||
libvirt_access.syms: $(srcdir)/rpc/gendispatch.pl \
|
||||
$(REMOTE_PROTOCOL) Makefile.am
|
||||
|
@ -1512,6 +1517,19 @@ libvirt_access_lxc.syms: $(srcdir)/rpc/gendispatch.pl \
|
|||
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclsym \
|
||||
lxc LXC $(LXC_PROTOCOL) > $@
|
||||
|
||||
libvirt_access.xml: $(srcdir)/rpc/gendispatch.pl \
|
||||
$(REMOTE_PROTOCOL) Makefile.am
|
||||
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclapi \
|
||||
remote REMOTE $(REMOTE_PROTOCOL) > $@
|
||||
libvirt_access_qemu.xml: $(srcdir)/rpc/gendispatch.pl \
|
||||
$(QEMU_PROTOCOL) Makefile.am
|
||||
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclapi \
|
||||
qemu QEMU $(QEMU_PROTOCOL) > $@
|
||||
libvirt_access_lxc.xml: $(srcdir)/rpc/gendispatch.pl \
|
||||
$(LXC_PROTOCOL) Makefile.am
|
||||
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclapi \
|
||||
lxc LXC $(LXC_PROTOCOL) > $@
|
||||
|
||||
$(srcdir)/access/viraccessapicheck.h: $(srcdir)/rpc/gendispatch.pl \
|
||||
$(REMOTE_PROTOCOL) Makefile.am
|
||||
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclheader \
|
||||
|
|
|
@ -41,8 +41,8 @@ my $res = GetOptions("mode=s" => \$mode);
|
|||
die "cannot parse command line options" unless $res;
|
||||
|
||||
die "unknown mode '$mode', expecting 'client', 'server', " .
|
||||
"'aclheader', 'aclbody', 'aclsym' or 'debug'"
|
||||
unless $mode =~ /^(client|server|aclheader|aclbody|aclsym|debug)$/;
|
||||
"'aclheader', 'aclbody', 'aclsym', 'aclapi' or 'debug'"
|
||||
unless $mode =~ /^(client|server|aclheader|aclbody|aclsym|aclapi|debug)$/;
|
||||
|
||||
my $structprefix = shift or die "missing struct prefix argument";
|
||||
my $procprefix = shift or die "missing procedure prefix argument";
|
||||
|
@ -351,6 +351,13 @@ if ($mode eq "aclsym") {
|
|||
# Automatically generated by gendispatch.pl.
|
||||
# Do not edit this file. Any changes you make will be lost.
|
||||
__EOF__
|
||||
} elsif ($mode eq "aclapi") {
|
||||
print <<__EOF__;
|
||||
<!--
|
||||
- Automatically generated by gendispatch.pl.
|
||||
- Do not edit this file. Any changes you make will be lost.
|
||||
-->
|
||||
__EOF__
|
||||
} else {
|
||||
print <<__EOF__;
|
||||
/* Automatically generated by gendispatch.pl.
|
||||
|
@ -1641,7 +1648,8 @@ elsif ($mode eq "client") {
|
|||
}
|
||||
} elsif ($mode eq "aclheader" ||
|
||||
$mode eq "aclbody" ||
|
||||
$mode eq "aclsym") {
|
||||
$mode eq "aclsym" ||
|
||||
$mode eq "aclapi") {
|
||||
my %generate = map { $_ => 1 } @autogen;
|
||||
my @keys = keys %calls;
|
||||
|
||||
|
@ -1667,6 +1675,7 @@ elsif ($mode eq "client") {
|
|||
foreach my $hdr (@headers) {
|
||||
print "#include \"$hdr\"\n";
|
||||
}
|
||||
print "\n";
|
||||
} elsif ($mode eq "aclbody") {
|
||||
my $header = shift;
|
||||
print "#include <config.h>\n";
|
||||
|
@ -1676,8 +1685,12 @@ elsif ($mode eq "client") {
|
|||
print "#include \"virerror.h\"\n";
|
||||
print "\n";
|
||||
print "#define VIR_FROM_THIS VIR_FROM_ACCESS\n";
|
||||
print "\n";
|
||||
} elsif ($mode eq "aclapi") {
|
||||
print "<aclinfo>\n";
|
||||
} else {
|
||||
print "\n";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
foreach (@keys) {
|
||||
my $call = $calls{$_};
|
||||
|
@ -1699,6 +1712,8 @@ elsif ($mode eq "client") {
|
|||
print $apiname . "CheckACL;\n";
|
||||
}
|
||||
print $apiname . "EnsureACL;\n";
|
||||
} elsif ($mode eq "aclapi") {
|
||||
&generate_aclapi($call);
|
||||
} else {
|
||||
&generate_acl($call, $call->{acl}, "Ensure");
|
||||
if (defined $call->{aclfilter}) {
|
||||
|
@ -1835,5 +1850,41 @@ elsif ($mode eq "client") {
|
|||
print "}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub generate_aclapi {
|
||||
my $call = shift;
|
||||
|
||||
my $apiname = "vir" . $call->{ProcName};
|
||||
if ($structprefix eq "qemu") {
|
||||
$apiname =~ s/virDomain/virDomainQemu/;
|
||||
} elsif ($structprefix eq "lxc") {
|
||||
$apiname =~ s/virDomain/virDomainLxc/;
|
||||
}
|
||||
|
||||
print " <api name='$apiname'>\n";
|
||||
|
||||
my $acl = $call->{acl};
|
||||
foreach (@{$acl}) {
|
||||
my @bits = split /:/;
|
||||
print " <check object='$bits[0]' perm='$bits[1]'";
|
||||
if (defined $bits[2]) {
|
||||
print " flags='$bits[2]'";
|
||||
}
|
||||
print "/>\n";
|
||||
}
|
||||
|
||||
my $aclfilter = $call->{aclfilter};
|
||||
foreach (@{$aclfilter}) {
|
||||
my @bits = split /:/;
|
||||
print " <filter object='$bits[0]' perm='$bits[1]'/>\n";
|
||||
}
|
||||
|
||||
print " </api>\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($mode eq "aclapi") {
|
||||
print "</aclinfo>\n";
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue