OpenStack 的 Keystone V3 中引入了 Domain 的概念。引入这个概念后,关于 admin 这个role 的定义就变得复杂了起来。

本文测试环境是社区 Mitaka 版本。
1. Domain,project,user,role,token 的概念和关系
1.1 概况
简单来说,
它们之间的关系用一个不完整的图来表示:
说明:
1.2 Token scope 和 Scoped token
官方文档在这里,我这里写的只是我的理解。
Token 是针对不同 scope 认证状态,这里的 scope 是指 project 和 domain,因此一共有三种 scoped token:
下文有获取不同类型 token 的方法的描述。
2. 各种 admin
admin 是一种特别的 role。下面分两种情况讨论。
2.1 使用默认 policy.json 时候的 admin 的权限
2.1.1 Identity 资源的 admin 权限
对 Identiy 项目中的大多数资源的操作都需要 admin 权限,比如:
"identity:get_user": "rule:admin_required", "identity:list_users": "rule:admin_required", "identity:create_user": "rule:admin_required", "identity:update_user": "rule:admin_required", "identity:delete_user": "rule:admin_required",
也就是说,以 user 为例,如果一个用户没有 admin 角色,那么他将不能对 user 做任何操作。而 policy.json 文件中对 admin 的约束非常简单:
"admin_required": "role:admin or is_admin:1",
也就是说,满足两个条件中的一个,它就是 administrator:
从 policy.json 文件可以看出来,只要赋予一个用户 admin 角色,那么他就是 administrator 了,可以操作 OpenStack cloud 内的所有资源。
2.1.2 OpenStack 基础设施资源的权限控制
以 Cinder 为例,它也使用 policy.json 文件进行 role 的 policy 控制,它区分了 admin,project owner 和普通 user 的权限:
"context_is_admin": "role:admin", "admin_or_owner": "is_admin:True or project_id:%(project_id)s", "default": "rule:admin_or_owner", "admin_api": "is_admin:True", "volume:create": "", "volume:delete": "rule:admin_or_owner", "volume:get": "rule:admin_or_owner", "volume:get_all": "rule:admin_or_owner", "volume:get_volume_metadata": "rule:admin_or_owner",
可见:
2.2 使用 policy.v3cloudsample.json 时候的 admin 的权限
从上面 2.1.1 可以看出,使用默认 policy.json 文件时的 admin 权限控制非常粗,不能支持 Keystone V3 API 中引入的域的概念。因此,社区提供了支持多域的 policy.v3cloudsample.json 文件。
2.2.1 Identity 中的 admin
"admin_required": "role:admin", "cloud_admin": "role:admin and (token.is_admin_project:True or domain_id:2b871f5dba704f74923ac01b4fcd7205)", "service_role": "role:service", "service_or_admin": "rule:admin_required or rule:service_role", "owner" : "user_id:%(user_id)s or user_id:%(target.token.user_id)s", "admin_or_owner": "(rule:admin_required and domain_id:%(target.token.user.domain.id)s) or rule:owner", "admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s", "service_admin_or_owner": "rule:service_or_admin or rule:owner",
它定义了几种 admin:
cloud admin (cloud_admin):必须拥有 admin role;其 token 在 admin project 内 或者在指定的 domain 内。Cloud admin 的主要职责是
domain admin:必须拥有 admin role;token 的 domain id 必须和被操作资源(包括user,project 等) 的 domain id 相同。其主要职责包括
只有 Cloud admin 拥有的一些权限:
只有 Domain admin 拥有的一些权限(当然这些权限 cloud admin 都拥有):
2.2.2 示例规则说明
"admin_required": "role:admin", "identity:create_project": "rule:admin_required and domain_id:%(project.domain_id)s", "identity:get_project": "rule:admin_required and domain_id:%(target.project.domain_id)s", "identity:list_projects": "rule:admin_required and domain_id:%(domain_id)s",
先来看create_project,首先要求 admin角色,需要注意的是and的后半句 domain_id:%(project.domain_id)s,这条规则的意思就是 create_project 时,使用的token的 domain_id 必须等于project所在的domain的domain_id。
也就是如下场景:
1.为userA在domainA的范围内赋予admin的权限
2.userA指定domainA作为scope,申请一个domainA scope的tokenA
3.userA使用tokenA,去创建project,创建project时domain_id参数必须为domainA的id
4.创建project成功
这里有几个关键点需要注意:
这样一条规则的意义在于,可以限制只有在domainA内有权限的用户才能在domainA创建project。
get_project 比较好理解,就是查询的project的 domain_id 必须和token的 domain_id 相同,也就是只能查询 token 所在范围内的project。
list_project 是查询出所有的project,但是会根据token的domain_id过滤,然后剩下所有和token的domain_id相同的project。
keystone 增加了 domain 这样一个概念之后,其实也就把 keystone 本身的资源 user、project、group 按照 domain 给做了一个划分,可以做到在 domain 范围内的对于user、project和group的管理。
3. 多域(multi-domain)的相关操作
3.1 启用多域 policy.json
1. Keystone 使用普通的 policy.json 文件,使用 admin 用户,创建 admin_domain domain,cloud_admin user 并授予其 admin role
openstack domain create admin_domain openstack user create --domain admin_domain --password 1111 --description "Cloud admin" cloud_admin openstack role add --domain admin_domain --user cloud_admin admin
2. 使用 policy.v3cloudsample.json
使用policy.v3cloudsample.json 覆盖 /etc/keystone/policy.json,并做如下修改(蓝色部分为上一步说创建的 admin_domain 的 id):
复制代码 代码如下:
"cloud_admin": "role:admin and (token.is_admin_project:True or domain_id:2b871f5dba704f74923ac01b4fcd7205)"
3. 重启 keystone service
3.2 操作
1. 获取 cloud_admin 用户 scoped domain 'admin_domain' token
CLOUD_ADMIN_TOKEN=$(\
curl http://localhost:5000/v3/auth/tokens \
-s \
-i \
-H "Content-Type: application/json" \
-d '
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"domain": {
"name": "admin_domain"
},
"name": "cloud_admin",
"password": "password"
}
}
},
"scope": {
"domain": {
"name": "admin_domain"
}
}
}
}' | grep ^X-Subject-Token: | awk '{print $2}' )
注意 Keystone token 分为两大类:domain-scoped token 和 project-scoped token,各自需要使用不同的 scope 目标:
--os-domain-name <auth-domain-name> | --os-domain-id <auth-domain-id>
Domain-level authorization scope (name or ID)
--os-project-name <auth-project-name> | --os-project-id
<auth-project-id>
Project-level authentication scope (name or ID)
其中 domain-scoped token 用于操作 domain 范围内的资源,包括 projects 和 users;project-scoped token 用于操作 project 范围的资源。可以简单地认为,前者适合于 cloud admin 和 domain admin;后者合适于 project admin 和 标准 user。
2. 创建域 dom1
ID_DOM1=$(\
curl http://localhost:5000/v3/domains \
-s \
-H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '
{
"domain": {
"enabled": true,
"name": "dom1"
}
}' | jq .domain.id | tr -d '"')
3. 在 dom1 中创建第一个用户 adm1
ID_ADM1=$(\
curl http://localhost:5000/v3/users \
-s \
-H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d "
{
\"user\": {
\"description\": \"Administrator of domain dom1\",
\"domain_id\": \"$ID_DOM1\",
\"enabled\": true,
\"name\": \"adm1\",
\"password\": \"password\"
}
}" | jq .user.id | tr -d '"')
4. 赋予用户 adm1 'admin' role
curl -X PUT http://localhost:5000/v3/domains/${ID_DOM1}/users/${ID_ADM1}/roles/${ADMIN_ROLE_ID} \
-s \
-i \
-H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \
-H "Content-Type: application/json"
5. 获取 adm1 在 dom1 中的 token,同样是domain-scoped 的
ADM1_TOKEN=$(\
curl http://localhost:5000/v3/auth/tokens \
-s \
-i \
-H "Content-Type: application/json" \
-d '
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"domain": {
"name": "dom1"
},
"name": "adm1",
"password": "password"
}
}
},
"scope": {
"domain": {
"name": "dom1"
}
}
}
}' | grep ^X-Subject-Token: | awk '{print $2}' )
6. 在 dom1 中创建 prj1
ID_PRJ1=$(\
curl http://localhost:5000/v3/projects \
-s \
-H "X-Auth-Token: $ADM1_TOKEN" \
-H "Content-Type: application/json" \
-d "
{
\"project\": {
\"enabled\": true,
\"domain_id\": \"$ID_DOM1\",
\"name\": \"prj1\"
}\
}" | jq .project.id | tr -d '"' )
echo "ID of prj1: $ID_PRJ1"
7. 在 dom1 中创建标准用户 usr1
ID_USR1=$(\
curl http://localhost:5000/v3/users \
-s \
-H "X-Auth-Token: $ADM1_TOKEN" \
-H "Content-Type: application/json" \
-d "
{
\"user\": {
\"default_project_id\": \"$ID_PRJ1\",
\"description\": \"Just a user of dom1\",
\"domain_id\": \"$ID_DOM1\",
\"enabled\": true,
\"name\": \"usr1\",
\"password\": \"password\"
}
}" | jq .user.id | tr -d '"' )
echo "ID of user usr1: $ID_USR1"
8. 赋予 usr1 Member 权限
MEMBER_ROLE_ID=$(\
curl http://localhost:5000/v3/roles?name=Member \
-s \
-H "X-Auth-Token: $ADM1_TOKEN" \
| jq .roles[0].id | tr -d '"' )
curl -X PUT http://localhost:5000/v3/projects/${ID_PRJ1}/users/${ID_USR1}/roles/${MEMBER_ROLE_ID} \
-s \
-i \
-H "X-Auth-Token: $ADM1_TOKEN" \
-H "Content-Type: application/json"
3.3 使用 OpenStack CLI 操作
经过测试,获得如下结果:
1. 使用 cloud_admin 用户在 openstack CLI 操作都正常
2. 使用 domain admin 用户 adm1 用户在 OpenStack CLI 中不正常
从 OpenStac CLI 文档上看,可以通过下面的方法获取不同 scoped token:
--os-domain-name <auth-domain-name> | --os-domain-id <auth-domain-id> Domain-level authorization scope (name or ID) --os-project-name <auth-project-name> | --os-project-id <auth-project-id> Project-level authentication scope (name or ID)
但是实际测试中,使用 --os-domain-name 无法获取期望的 domain-scoped token:
root@controller:/home/sammy# openstack --os-domain-name dom1 --os-username adm1 --os-password password --os-user-domain-name dom1 user list You are not authorized to perform the requested action: identity:list_users (HTTP 403) (Request-ID: req-ea4b10-0a35-4d88-907f-bab181544f40)
调试发现,此时的token 自带有 project_id,而不带有 domain_id。还需要进一步确认是否是个 bug。
一个 workaround 是,对于这种 domain admin 用户,需要首选获取 domain scoped token,然后通过 curl 操作,比如要获取 domain 内的project 列表:
root@controller:/home/sammy# curl -sX GET -H "X-Auth-Token:$ADM1_TOKEN" http://mysqlserver:5000/v3/projects?domain_id=db7de29b35dd450284dc99bc0a6474ca
{"links": {"self": "http://mysqlserver:5000/v3/projects?domain_id=db7de29b35dd450284dc99bc0a6474ca", "previous": null, "next": null}, "projects": [{"is_domain": false, "description": "", "links": {"self": "http://mysqlserver:5000/v3/projects/7ff06beb0045405f8bebcda166f47f04"}, "enabled": true, "id": "7ff06beb0045405f8bebcda166f47f04", "parent_id": "db7de29b35dd450284dc99bc0a6474ca", "domain_id": "db7de29b35dd450284dc99bc0a6474ca", "name": "prj1"}
3. 从结果看, Mitaka 版本的 OpenStack CLI 对多域的支持情况如下:
3.4 Horizon 对多域的支持
3.4.1 准备工作
1. 修改 /etc/openstack-dashboard/local_settings.py 文件:
OPENSTACK_API_VERSIONS = {
"data-processing": 1.1,
"identity": 3,
"volume": 2,
"compute": 2,
}
# Set this to True if running on multi-domain model. When this is enabled, it
# will require user to enter the Domain name in addition to username for login.
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
2. 将 keystone 使用的支持多域的 policy.json 文件拷贝到目录/etc/openstack-dashboard/keystone_policy.json,然后修改文件local_settings.py:
POLICY_FILES = {
'identity': 'keystone_policy.json'
}
3. 重启 horizon 服务,此时可以使用 domain 和 username,password 登录
4. 简单测试了一下,发现还是有不少问题。
比如 cloud admin dashboard 中只能出来它所在的domain,而不能出来所有的 domains:
以domain admin 登录,直接报错:
以普通用户登录,还能显示 Admin/System 面板。
备注:Keystone V3 中的概念较多,涉及的面较广,本文只是说明了一部分,甚至不是很准确。接下来会根据需要持续更新。
# OpenStack
# Mitaka
# domain
# admin
# Fuel快速安装OpenStack图文教程
# 一步一步教你安装openstack(图文)
# openstack 重启的服务命令整理总结
# OpenStack之日志详细介绍
# CentOS 6.4下安装部署OpenStack云计算平台的方法
# Fuel 30 分钟快速安装OpenStack(图文教程)
# OpenStack之虚机热迁移的代码详细解析
# 什么是OpenStack 开源的云计算管理平台项目
# Openstack 使用migrate进行数据库升级实现方案详细介绍
# CentOS 一键安装Openstack详细介绍
# 是一个
# 这是
# 是指
# 不可以
# 也就是说
# 为例
# 可以看出
# 重启
# 需要注意
# 普通用户
# 基础设施
# 的是
# 是个
# 文档
# 也不
# 在这里
# 是一种
# 会有
# 你可以
# 第一个
相关文章:
如何使用Golang table-driven基准测试_多组数据测量函数效率
行程制作网站有哪些,第三方机票电子行程单怎么开?
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
建站之星后台管理:高效配置与模板优化提升用户体验
建站三合一如何选?哪家性价比更高?
如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法
如何用PHP工具快速搭建高效网站?
表情包在线制作网站免费,表情包怎么弄?
c++ stringstream用法详解_c++字符串与数字转换利器
专业网站制作服务公司,有哪些网站可以免费发布招聘信息?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
网站制作免费,什么网站能看正片电影?
建站之星后台密码遗忘或太弱?如何重置与强化?
在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?
平台云上自主建站:模板化设计与智能工具打造高效网站
广州美橙建站如何快速搭建多端合一网站?
如何将凡科建站内容保存为本地文件?
中山网站制作网页,中山新生登记系统登记流程?
北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?
制作网站外包平台,自动化接单网站有哪些?
招商网站制作流程,网站招商广告语?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
做企业网站制作流程,企业网站制作基本流程有哪些?
手机网站制作与建设方案,手机网站如何建设?
盘锦网站制作公司,盘锦大洼有多少5G网站?
寿县云建站:智能SEO优化与多行业模板快速上线指南
如何用狗爹虚拟主机快速搭建网站?
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?
网站网页制作专业公司,怎样制作自己的网页?
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
如何零基础在云服务器搭建WordPress站点?
如何快速上传自定义模板至建站之星?
建站之星2.7模板:企业网站建设与h5定制设计专题
股票网站制作软件,网上股票怎么开户?
建站之星价格显示格式升级,你的预算足够吗?
如何通过主机屋免费建站教程十分钟搭建网站?
建站之星如何优化SEO以实现高效排名?
微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?
公司门户网站制作流程,华为官网怎么做?
山东网站制作公司有哪些,山东大源集团官网?
已有域名如何免费搭建网站?
如何基于PHP生成高效IDC网络公司建站源码?
网站制作话术技巧,网站推广做的好怎么话术?
如何通过NAT技术实现内网高效建站?
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
如何在云主机上快速搭建多站点网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。