Policy Definition: https://github.com/openstack/keystone/blob/stable/rocky/etc/policy.v3cloudsample.json
Policy Mapping: https://github.com/openstack/keystone/blob/stable/rocky/doc/source/getting-started/policy_mapping.rst
Policy Definition: https://github.com/openstack/glance/blob/stable/rocky/etc/policy.json
Policy Mapping: https://github.com/openstack/glance/blob/stable/rocky/doc/source/admin/policies.rst
Policy Definition: https://github.com/openstack/cinder/blob/stable/rocky/cinder/tests/unit/policy.json
Policy Mapping: https://github.com/openstack/cinder/blob/stable/rocky/cinder/policies/__init__.py
N.B - Cinder implements policy as code. Following snippet will render DocumentedRuleDefault
objects:
from importlib import import_module
from pprint import pformat
import sys
from oslo_policy.policy import DocumentedRuleDefault
SVC_MAP = dict(
keystone='keystone.common.policies',
cinder='cinder.policies',
nova='nova.policies',
heat='heat.policies'
)
def render_policies(service):
lib = import_module(SVC_MAP.get(service))
policies = list(filter(
lambda x: isinstance(x, DocumentedRuleDefault),
lib.list_rules())
)
def render_rule(rule):
if not isinstance(rule, DocumentedRuleDefault):
raise ValueError(rule)
def render_targets():
for op in rule._operations:
yield f"{op['method']} {op['path']}"
return f'{rule.name} {pformat(list(render_targets()))}'
yield from map(render_rule, sorted(policies, key=lambda x: x.name))
if __name__ == '__main__':
services = sys.argv[1:] or ('keystone', 'cinder', 'nova', 'heat')
for svc in services:
print('===', svc, '===')
try:
for policy in render_policies(svc):
print(policy)
except Exception as e:
print(e, file=sys.stderr)
Policy Definition: https://github.com/openstack/neutron/blob/stable/rocky/etc/policy.json
Policy Mapping:
extra:
Policy Definition: https://docs.openstack.org/nova/rocky/_downloads/nova.policy.yaml.sample
Policy Mapping: https://docs.openstack.org/nova/rocky/_downloads/nova.policy.yaml.sample
cinderclient call | policy action |
---|---|
.quotas.update() |
volume_extension:quotas:update |
.quotas.get() |
volume_extension:quotas:show |
.backups.list() |
backup:backup_project_attribute |
backup:get_all |
|
.volume_snapshots.list() |
volume:get_all_snapshots |
volume_extension:extended_snapshot_attributes |
|
.volumes.get() |
volume:get_all_snapshots |
volume_extension:extended_snapshot_attributes |
|
.volumes.get().detach() |
volume_extension:volume_actions:detach |
.volumes.get().delete() |
volume:delete |
volume:force_delete |
|
.volumes.list() |
volume:get_all |
volume_extension:volume_host_attribute |
|
volume_extension:volume_image_metadata |
|
volume_extension:volume_mig_status_attribute |
|
volume_extension:volume_tenant_attribute |
|
.volumes.create() |
volume:create |
volume:create_from_image |
|
volume:multiattach |
glanceclient call | policy action |
---|---|
.image_members.create() |
add_member |
keystoneclient call | policy action |
---|---|
.projects.get() |
identity:get_project |
.projects.create() |
identity:create_project |
.projects.delete() |
identity:delete_project |
.projects.list() |
identity:list_projects |
identity:list_user_projects |
|
.roles.get() |
identity:get_domain_role |
identity:get_role |
|
.roles.grant() |
identity:create_grant |
.role_assignments.list() |
identity:list_role_assignments |
identity:list_role_assignments_for_tree |
|
.users.get() |
identity:get_user |
.users.list() |
identity:list_users_in_group |
identity:list_users |
neutronclient call | policy action |
---|---|
.list_networks() |
get_network |
get_network:provider:network_type |
|
get_network:provider:physical_network |
|
get_network:provider:segmentation_id |
|
get_network:router:external |
|
.list_security_groups() |
get_security_group |
.create_security_rule() |
create_security_group_rule |
N.B. why no get_security_groups
?
Appears that one cannot enumerate all security groups w/o admin credentials
See: retrieve_all
parameter.
novaclient call | policy action |
---|---|
.availability_zones.list() |
os_compute_api:os-availability-zone:detail |
os_compute_api:os-availability-zone:list |
|
.flavors.list() |
os_compute_api:os-flavor-access |
os_compute_api:os-flavor-extra-specs:index |
|
os_compute_api:os-flavor-rxtx |
|
.flavor_access.add_tenant_access() |
os_compute_api:os-flavor-access:add_tenant_access |
.floating_ips.list() |
DEPRECATED IN ROCKY |
.floating_ips.find().delete() |
DEPRECATED IN ROCKY |
.images.get() |
DEPRECATED IN ROCKY: see novaclient.glance.find_image() |
.quotas.get() |
os_compute_api:os-quota-sets:detail |
os_compute_api:os-quota-sets:show |
|
.limits.get() |
os_compute_api:limits |
os_compute_api:os-used-limits |
|
.quotas.update() |
os_compute_api:os-quota-sets:update |
.security_group_rules.create() |
DEPRECATED IN ROCKY |
.security_groups.get() |
DEPRECATED IN ROCKY |
.servers.get() |
os_compute_api:os-flavor-extra-specs:index |
os_compute_api:os-security-groups |
|
os_compute_api:servers:show |
|
os_compute_api:servers:show:host_status |
|
.servers.get().delete() |
os_compute_api:servers:delete |
.servers.create() |
network:attach_external_network |
os_compute_api:servers:create |
|
os_compute_api:servers:create:attach_network |
|
os_compute_api:servers:create:attach_volume |
|
os_compute_api:servers:create:forced_host |
|
os_compute_api:servers:create:trusted_certs |
|
os_compute_api:servers:create:zero_disk_flavor |
|
.servers.list() |
os_compute_api:os-config-drive |
os_compute_api:os-extended-availability-zone |
|
os_compute_api:os-extended-server-attributes |
|
os_compute_api:os-extended-status |
|
os_compute_api:os-extended-volumes |
|
os_compute_api:os-hide-server-addresses |
|
os_compute_api:os-keypairs |
|
os_compute_api:os-server-usage |
|
os_compute_api:servers:detail |
|
os_compute_api:servers:detail:get_all_tenants |
|
os_compute_api:servers:index |
|
os_compute_api:servers:index:get_all_tenants |
|
os_compute_api:servers:show:host_status |
|
.servers.set_meta() |
os_compute_api:server-metadata:create |