Horizon不会为Openstack 增加一个功能,他更多的是一个演示demo。不过从Horizon dashboard开始学习Openstack是一个不错的选择。做Horizon开发需要和各个项目打角度,每个项目的功能很多都是需要通过Dashboard来展现。Horizon只是使用了Openstack部分API功能,很多功能可以根据你的需求去实现。
Openstack其他组建介绍
Nova
Openstack的核心,最初可以说是一套虚拟化管理程序,后台开始分拆做减法,将一部分功能实现交由其他组件实现。
Keystone
提供身份认证和授权,目前起功能还很有限。(HA)
Glance
镜像管理组件,其功能其实相对比较简单。(后端的存储)
Neutron
网路管理组件,有非常大的发展潜力。(值得深究)
Cinder
块存储管理组件。(支持开源的sheepdop,ceph;商业的估计会落户IBM,因为他最积极)
Swift
对象存储组件。
Ceilometer
计量监控组件。
Heat
这个项目是要解决虚拟机的软件部署的问题。
Trove
数据库服务。
sudo apt-get install -y git
yum install -y git
git clone https://github.com/openstack/horizon.git
cd horizon
python ./tools/install_venv.py
cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
修改文件中的
OPENSTACK_HOST以及debug开关
./tools/with_venv.sh python manage.py runserver ip:port
如果出现无法找到
openstack_dashboard.settings
,可
cd horizon-2014-1-1/.venv/lib/python2.7/site-packages/
echo “xxx/horizon” > horizon.pth
在开发环境下修改代码后自动生效,无需重启
Horzion
。
源代码中加入:
if sys.getdefaultencoding() != 'gbk':
reload(sys)
sys.setdefaultencoding('gbk')
default_encoding = sys.getdefaultencoding()
|
./tools/with_venv.sh pip install oslo.config
|
修正 horizon目录包含公共的组件table,tab,form等。
STATIC主要指的是如css,js,images这样文件,在settings里面可以配置STATIC_ROOT和STATIC_URL,配置方式与MEDIA_ROOT是一样的,但是要注意STATIC_ROOT与MEDIA_ROOT位置不能一样。
STATIC文件一般保存在以下位置:
./tools/with_venv.sh python manage.py collectstatic
也就是说一个项目引用了很多app,那么这个项目所需要的css,images等静态文件是分散在各个app的static文件的,比较典型的是admin应用。当你要发布时,需要将这些分散的static文件收集到一个地方就是STATIC_ROOT。运行compress会将js,css进行压缩。
./tools/with_venv.sh python manage.py compress
STATIC_URL的含义与MEDIA_URL类似。
horizon-2014-1-1/horizon/templates/base.html layout布局
Horizon的用户认证由django_openstack_auth,他是一个Django的认证模块,具体信息请下载源代码查看。Horizon在settings.py中配置了用户登录认证的后台服务类AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)
,
Django
框架会自动调用
openstack_auth.backend.KeystoneBackend
中的
authenticate方法生成User对象,然后设置session。Horizon判断user是否是superuser决定跳转到对应的dashboard面板。
详细代码
Horizon的源码中,包含两个代码文件夹,horizon和openstack_dashboard。Horizon这个包是一些在django基础上写的通用组件,表格(table),标签页(tab),表单(form),面包屑导航(browser),工作流(workflow),这些代码和openstack的具体业务逻辑没有什么关系,如果做一个新的django项目,可以复用Horizon这个包中的代码。horizon/base.py中还实现了一套dashboard/panel机制,使得Horizon面板上所有的dashboard都是“可插拔”的,所有的panel都是“动态加载”的。
openstack_dashboard/dashboards/中是各个面板的具体实现代码,其中包括各个面板的模板文件和后端service交互的业务逻辑代码等。
Horizon这套面板的设计分成三层:Dashboard->PanelGroup->Panel,dashboard如project,admin等。每一个dashboard都是django中的一个app,django中的app可以包含自己独有的url设定,模板,和业务逻辑代码。每个dashboard下定义了一系列的PanelGroup,里面有一系列的子panel。
Horizon处理登录
参看openstack_auth部分。
dasboard自己拥有的panel
每个dashboard模块下都有一个dasbboard.py文件里面定义了属于当前dashboard的PanelGroup和各个PanelGroup下的Panel,在Horizon模块被导入的时候会去依次遍历Dasboard->PanelGroup->Panel,所有的dashboard注册到Horizon命名空间下,各个panel注册到自己的dashboard命名空间下。
每个panel是找到自己的模板的
Django中的有template loader概念,简单的说,template loader就是一个处理request的视图寻找自己的模板文件路径的方法,loader的定义在openstack_dashboard.settings中的TEMPLATED_LOADERS变量。
TEMPLATED_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'horizon.loaders.TemplateLoader',
)
举例:
当点击左侧project(这是个dashboard)下的instance(这是个panel)标签时,页面会跳转到http://localhost/project/instances这个url,panel在的视图类中写了template_name=“project/instances/index.html”,查找这个文件的顺序是:
普通用户看不到admin面板
显不显示某panel,实际上并不由Horizon控制,而是由Keystone控制。一个后端的webservice需要集成进openstack的话,第一步是在Keyston处登记,在Keyston的service,endpoint这两张表内写入该service的的一些元数据信息(包括url地址)。Horizon控制面板是否显示用了一套叫permission的机制,比如Container(swift的panel)要显示的条件是”openstack.services.object-store”。用户的登陆后的token中又service catalog信息,catalog中必须包含object-store这个service,满足,container这个panel就会注册到project这个dashboard之下,页面上就能显示,如果Keyston中没有swift的catalog信息,Horizon就不会注册container这个panel,swift的面板就不会显示。heat同理。
Admin dashboard这个类中写的permission是”openstack.roles.admin”,则admin这个面板显示的条件是当前登录的用户有admin这个role,满足的用户就能看到admin dashbaord.要了解permission的具体实现请看openstack_auth/backend.py 模块.
使用命令添加dashboard和panel
/home/hugb/code/horizon-2014-1-1/tools/with_venv.sh python /home/hugb/code/horizon-2014-1-1/manage.py startdash xxx
/home/hugb/code/horizon-2014-1-1/tools/with_venv.sh python /home/hugb/code/horizon-2014-1-1/manage.py startpanel xc -d openstack_dashboard.dashboards.xxx --target auto
自定义
css
要对
Horizon
的
css
样式做自定制,可以修改
openstack_dashboard/static/less
目录下的
less
文件
自定义
js
要对
Horizon
中
js
的行为做定制,可以修改
horizon/static/horizon/js/
目录下的文件
,Horizon
的
js
文件都是针对具体某个页面组件做的行为定制,比如
form
提交时的行为,
tab
切换的行为,所以都放在
Horizon
目录下而不在
openstack_dashboard
目录下。
python setup.py sdist
Horzion blueprint
Django模板语言
二:keystone使用总结
Keystone是Openstack框架中的一个重要组成部分,负责身份认证、服务管理、服务规则和服务令牌的功能, 它实现了Openstack的Identity API。Keystone类似一个服务总线,或者说是整个Openstack框架的注册表,其他服务通过Keystone来注册其服务,任何服务之间相互的调用,都需要经过Keystone的身份验证来获得目标服务。Keystone包含两个主要部件:验证与服务目录。
验证部件提供了一套基于令牌的验证服务,主要包含以下几个概念:
租户(Tenant):使用相关服务的一个组织(一个租户可以代表一个客户、账号、公司、组织或项目),必须指定一个相应的租户(Tenant)才可以申请OpenStack服务。在Swift中,一个租户可以拥有一定的存储空间,拥有多个容器,可以理解为一个公司拥有一大块存储空间。
用户(User):表示拥有用户名、密码、邮箱等账号信息的个人,用户能够申请并获得访问资源的授权。用户拥有证书,可以与一个或多个租户关联。经过身份验证后,会为每个关联的租户提供一个特定的令牌。一个用户可以在不同的租户中被分配不同的角色。以Swift为例,我们可以这样理解:租户是一个公司,拥有一大块存储空间,用户是个人,是该公司的员工,能够根据用户的角色访问公司的部分或全部存储空间,当然这个员工可以同时在其他公司兼职,拥有其他公司的存储空间;如果某个公司只有一个员工,即该员工拥有公司的全部存储空间,此时的用户就类似于金山快盘的用户了。
证书(Credentials):为了给用户提供一个令牌,需要用证书来唯一标识一个用户的密码或其它信息。
令牌(Token):一个令牌是一个任意比特的文本,用于与其它OpenStack服务来共享信息,Keystone以此来提供一个Central Location,以验证访问OpenStack服务的用户。一个令牌可以是scoped或unscoped。一个scoped令牌代表为某个租户验证过的用户,而unscoped令牌则仅代表一个用户。令牌的有效期是有限的,可以随时被撤回。
角色(Role):代表特定的租户中的用户操作权限,一个角色是应用于某个租户的使用权限集合,以允许某个指定用户访问或使用特定操作。角色是使用权限的逻辑分组,它使得通用的权限可以简单地分组并绑定到与某个指定租户相关的用户。
服务目录部件(Service Catalog)提供了一套REST API服务端点列表并以此作为决策参考,主要包含以下几个概念:
服务(Service):一个OpenStack服务,例如Nova、Swift、Glance或Keystone。一个服务可以拥有一个或多个端点,用户可以通过它与OpenStack的服务或资源进行交互。
端点(Endpoint):一个可以通过网络访问的地址(例如一个URL),代表了OpenStack服务的API入口。端点也可以分组为模板,每个模板代表一组可用的OpenStack服务,这些服务是跨区域(regions)可用的,例如将多个Swift Proxy Server分别配置为不同的域(regionOne、regionTwo等)。
模板(Template):一个端点集合,代表一组可用的OpenStack服务端点。
环境类型: 详细信息
机器类型: PC物理机
操作系统: Ubuntu-12.04-desktop-64位
用户类型: hugb
数据库: sqlite3
IP地址: 192.168.1.180
请务必确保各处安装的Keystone与python-keystoneclient的版本统一。
sudo rpm -ivh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo yum install python-sqlite2 python-lxml python-greenlet-devel python-ldap
sudo yum install openstack-utils openstack-keystone python-keystoneclient
sudo apt-get update
sudo apt-get install ubuntu-cloud-keyring
cat <<EOF >>/etc/apt/sources.list
deb http://ubuntu-cloud.archive.canonical.com/ubuntu precise-proposed/grizzly main
deb http://ubuntu-cloud.archive.canonical.com/ubuntu precise-updates/grizzly main
EOF
sudo apt-get update && apt-get -y dist-upgrade
sudo apt-get install keystone python-keystoneclient python-keystone keystone-doc
(下面所有都是基于此进行的操作)
克隆keystone知识库。
git clone http://github.com/openstack/keystone.git
cd keystone
安装依赖。
sudo apt-get install python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev
安装虚拟环境,安装时会自动将python依赖装上,然后切换到虚拟环境。
python tools/install_venv.py
source .venv/bin/activate
如果不使用python虚拟环境,直接安装python依赖,需要预先安装setuptools,pip。
wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
easy_install pip
pip-requires中记录了运行Keystone程序所需的依赖项。
pip install requirements.txt
test-requires中记录了Keystone动态开发与测试所需的依赖项。需要特别注意的是,安装tools/test-requires依赖项时会自动重新安装Swift。因此,如果电脑上已经安装了Swift,就不可以再执行“pip install -r tools/test-requires”命令了(该命令会覆盖掉之前安装的Swift程序)。如果你不小心覆盖掉了之前安装的Swift程序,也无需担心,执行python setup.py develop,重新安装你的Swift程序和其客户端即可。
pip install -r test-requirements.txt
以开发模式安装包。
python setup.py develop
(正式环境:python setup.py install)
验证keystone是否已经装上。
python
>>> import keystone
>>>
配置文件
./etc/keystone.conf keystone的核心配置文件
./etc/keystone-paste.ini WSGI pipeline 配置
./etc/logging.conf 日志配置
./etc/policy.json 定义user RBAC权限,定义了Identity服务的访问策略
./etc/default_catalog.templates 目录服务模版配置
Keystone.conf 各节配置
[DEFAULT] 一般配置
[sql] 可选的后端存储配置
[identity] 身份认证配置
[credential
[trust]
[os_inherit]
[catalog] 服务目录配置
只有两个选项,driver,template_file
driver dynamic, sql-based backend (supports API/CLI-based management commands),A temp late_file does not need to be defined for the sql.Catalog driver.
[token] token driver & token provider configuration
[policy] policy system driver configuration for RBAC
[ec2] Amazon EC2认证配置
[assignment]
[ssl] SSL配置
[signing] 基于token的PKI(Public Key Infrastructure)签名
[ldap] LDAP配置
[auth] Authentication plugin configuration
默认提供了三种认证方法password,token,external,另外也可以自己实现认证插件。Methods 插件名称列表,以逗号分割,<plugin name>插件的实现类。
[paste_deploy] Pointer to the PasteDeploy configuration file
config_file如果是相对路径,则keystone在keystone.conf所在目录下查找。如果没有指定, 则WSGI pipeline会从keystone.conf加载配置。
主要配置选项
[DEFAULT]
admin_token = ADMIN
admin_token参数是用来访问Keystone服务的,即Keystone服务的Token。默认为ADMIN,当然也可以改成别的。客户端可以使用该Token访问Keystone服务、查看信息、创建其他服务等。
public_port = 5000
Keystone提供的认证授权服务监听的端口,通常为公网(外网),也可以是内网。
admin_port = 35357
Keystone提供的认证授权、系统管理服务监听的端口,通常为内网。除了认证授权功能外,用户需要访问该端口来进行管理员操作,如创建删除Tenant、User、Role、Service、Endpoint等。
[sql]
connection = sqlite:///keystone.db
此处为数据库参数,默认使用sqlite,并且指定数据库文件的存放位置,keystone.db表示在主目录下创建keystone.db文件,用于存放数据。也可以指定其他存储位置,例如sqlite:////var/lib/keystone/keystone.db。当然也可以使用mysql,如mysql://root:[email protected]/keystone,其中192.168.1.180为数据库地址,keystone为数据库名称,root为用户名,123456为访问密码。需要事先安装mysql,并且创建名为keystone的数据库,设置用户名密码。
[token]
driver = keystone.token.backends.memcache.Token
如果keystone使用memcached,确保memcached主机的系统时间设置为UTC,避免密玥失效时间不一致。
bind = kerberos
token绑定到kerberos服务器。
[signing]
token_format = PKI
此处需要特别注意,新版本中默认Token为PKI,因而需要为此设置PKI认证,较为麻烦,可改为UUID以方便使用,UUID是一个几十位的随机字符串。
[os_inherit]
enabled = True
分配roles给domain而不影响domain本身。
./bin/keystone 用于配置keystone
./bin/keystone-manage 用于引导用户配置keystone的数据
./bin/keystone-all 运行keystone服务
在终端执行keystone-all --help、keystone-manage --help、keystone --help命令,即可查看Keystone的帮助信息。
同步数据库schema,Keystone会自动连接数据库,完成Table创建等工作。
keystone-manage db_sync
然后,sqlite3数据库会创建文件~/keystone.db(视上文中的配置文件而定),我们可以查看数据库中的Table。首先使用sqlite3 ~/keystone.db命令打开数据库,然后使用.table命令查看所有Table,包括Tenant、User、Role、Service、Endpoint等。
至此,我们已经成功地完成了Keystone服务的安装与配置,完事具备,可以启动Keystone服务了。
keystone-all
参数
--config-file 指定配置文件,如果没有指定,按以下顺序~/keystone/,~/,/etc/keystone/,/etc/到其目录 下查找。
--config-dir 指定配置文件目录
PKI 证书
可以使用keystone-manager pki_setup来生成,注意其目录结构和读写权限。
SSL
keystone-manage ssl_setup 生成带ssl的签名认证的相关文件。
token认证
export SERVICE_TOKEN=ADMIN
export SERVICE_ENDPOINT=http://192.168.1.180:35357/v2.0
密码认证
export OS_USERNAME=my_username
export OS_PASSWORD=my_password
export OS_TENANT_NAME=my_tenant
export OS_AUTH_URL=http://192.168.1.180:35357/v2.0
SERVICE_TOKEN就是访问Keystone服务时使用的Token,与配置文件keystone.conf中的信息相对应,默认为ADMIN。
SERVICE_ENDPOINT就是Keystone的Endpoint,即API入口,Keystone服务的接入口。其中,“192.168.1.180”为安装Keystone服务的机器的IP,“35357”为Keystone提供的认证授权和系统管理服务监听的端口(通常为内网),用户需要访问该端口来进行管理员操作,如创建删除Tenant、User、Role、Service、Endpoint等。
于是,客户端就可以使用名为ADMIN的Token,通过给定的访问地址http://192.168.1.180:35357/v2.0来访问Keystone服务了。
首先,我们分别执行以下命令,通过访问Keystone服务来查看几个重要数据库Table的内容,包括Tenant、User、Role、Service和Endpoint。当然,结果必然是空的,因为我们还没有添加任何Tenant、User、Role、Service以及Endpoint,但结果已经证明Keystone已经在正常工作了。
keystone tenant-list
keystone user-list
keystone role-list
keystone service-list
keystone endpoint-list
keystone user-list
keystone tenant-create --name=demo
keystone --token=secrete --endpoint=http://192.168.1.180:35357/v2.0/ user-list
keystone --token=secrete --endpoint=http://192.168.1.180:35357/v2.0/ tenant-create --name=demo
keystone --os_username=admin --os_password=secrete --os_tenant_name=admin user-list
keystone --os_username=admin --os_password=secrete --os_tenant_name=admin tenant-create –name=demo
下面,我们将按照自己的要求来手动添加Tenant、User、Role、Service、Endpoint等信息。
我们将创建名称为admin的Tenant(租户)、名称为admin的User(用户)以及名称为admin的Role(角色),并将它们关联起来。最终的结果表现为:一个名叫admin的用户,其拥有名为admin的角色身份,并且能够使用名为admin的租户。
创建Tenant,租户名为admin,描述信息为Admin Tenant。请记住该命令生成的Tenant id,下面添加User时需要用到。
keystone tenant-create --name admin --description "Admin Tenant"
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 tenant-create --name admin --description "Admin Tenant"
创建User,用户名为admin,密码为admin。请记住该命令生成的User id,下面的关联命令需要用到。
keystone user-create --name=admin --pass=admin --tenant_id=[uuid] [email protected]
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 user-create --name admin --pass admin --tenant-id 68fa672315d74ab68eae36ea58e58c27
创建Role,角色名为admin。请记住该命令生成的Role id,下面的关联命令需要用到。
keystone role-create --name admin
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 role-create --name admin
创建Service,服务名为test,描述信息为Service test。请记住该命令生成的Serviceid,下面添加Endpoint时需要用到。
keystone service-create --name test --type=other--description="Service test"
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 service-create --name ae2 --type ae2 --description "pass"
创建Endpoint
keystone endpoint-create --region RegionOne --service-id=15c11a23667e427e91bc31335b45f4bd --publicurl=http://192.168.1.180:5001/v2.0 --internalurl=http://192.168.1.180:5002/v2.0 --adminurl=http://192.168.1.180:5003/v2.0
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 endpoint-create --region RegionOne --service-id e1bab5452f9b49dcacb4974daa448be7 --publicurl http://192.168.1.180:8212/v2 --internalurl http://192.168.1.180:8212/v2 --adminurl http://192.168.1.180:8212/v2
最后,我们要使用上述三个id,并通过下面的命令来将三者关联起来。
keystone user-role-add --user-id [uuid] --tenant-id [uuid] --role-id [uuid]
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 user-role-add --user-id e5787454c62845ffac026ae2a8b4e31f --tenant-id 68fa672315d74ab68eae36ea58e58c27 --role-id 89e0d9dfec334fa3bf29f8fa82a5c781
我们再使用list命令查看一下Tenant、User、Role、Service和Endpoint的信息。
上面已经完成了Tenant、User和Role的创建,并将三者关联起来,于是我们就可以使用User的用户名和密码来访问Keystone,获取用于访问Tenant的Token了。我们将使用curl命令来访问Keyston以获取授权,该命令需要给定四个参数,即tenantName(租户名)、username(用户名)、password(用户密码)以及认证授权申请地址(http://192.168.1.180:35357/v2.0/tokens或http://192.168.1.180:5000/v2.0/tokens都可以)。此外,返回信息会以json格式展现。
先尝试使用错误的密码进行访问,结果获取授权失败。返回信息中给出了相关错误提示信息。
curl -d '{"auth": {"tenantName": "admin", "passwordCredentials":{"username": "admin", "password": "admin1"}}}' -H "Content-type: application/json" http://192.168.1.180:35357/v2.0/tokens | python -mjson.tool
curl -d '{"auth": {"tenantName": "admin", "passwordCredentials":{"username": "admin", "password": "admin"}}}' -H "Content-type: application/json" http://192.168.1.0180:5000/v2.0/tokens | python -mjson.tool
curl -H "Content-type: application/json" -H "X-Auth-Token:xxxxxxxxxxxxxxxxx" http://192.168.1.180:35357/v2.0/tenants | python -mjson.tool
curl -H "Content-type: application/json" -H "X-Auth-Token:077f3e1836644711ad86f74600728d85" http://192.168.1.180:5000/v2.0/tenants | python -mjson.tool
然后使用正确的密码访问(http://192.168.1.180:35357/v2.0/tokens),结果成功获取授权。返回信息中包含了我们所需的Token,同时也显示了与本次请求相关的Tenant、User以及Role的信息。我们可以看到,Token的id,其授权通过的时间,其授权过期的时间。
curl -d '{"auth": {"tenantName": "adminTenant", "passwordCredentials":{"username": "admin", "password": "openstack"}}}' -H "Content-type: application/json" http://192.168.1.180:35357/v2.0/tokens | python -mjson.tool
使用已有的token认证
curl -d '{"auth": {"token": {"id": "xxxxxxx"}}}' -H "Content-type: application/json" http://192.168.1.180:35357/v2.0/tokens | python -mjson.tool
curl -d '{"auth": {"tenantName": "admin", "passwordCredentials":{"userId": "ecb3a45e4c204d84bb5c39e9e7b3783d", "password": "admin"}}}' -H "Content-type: application/json" http://192.168.1.180:35357/v2.0/tokens | python -mjson.tool
keystone-client提供了middleware实现token的认证,只需稍加配置keystone-paste.ini就可以使用。
PKI的token生成,用户拿着帐号密码[租户]身份信息去请求keystone /v2.0/tokens,keystone认证用户身份合法性。认证通过后,获取user和tenant信息,将其和meta信息组成一个数据字典与用户角色数据和服务目录数据组成一个新的数据结构。将该结构数据用证书和私钥进行签名。然后通过一定的字符串处理得到token。UUID的token生成比PKI简单许多,其就是一个uuid.uuid4().hex得到的字符串。
用户请求—>进入filter chain—>应用
filter chain中使用keystoneclient进行拦截处理,处理流程如下:
1.移除与token有关的header,防止伪造,这样一个用户就不能伪装认证,保证env没有与identity相关的数据。
2.取出token(X-Auth-Token和X-Storage-Token)。
3.在缓存中查找token,如果缓存中存在,说明已经在鉴权有效期内,直接返回相关数据。
4.如果没在缓存中,继续判断token格式是UUID还是PKI。
5.如果是PKI则token的前三个字符是MII。判断token有效性,验证签名,得到原始数据。
6.如果是UUID,用admin_token和该token去keystone认证,返回相关数据。
7.缓存token。
8.生成header用户自定义信息。
Step 1: Obtain an unscoped token from Keystone
用用户名和密码请求keystone,得到一个无作用域的token
Step 2: Discover tenants you have access to
用第一步的token请求keystone,得到租户列表
Step 3: Obtain a scoped token
用租户名,用户名和密码请求keystone,得到一个有作用域的token
Step 4: Invoke the target endpoint service API
调用endpoint,验证token,PKI/UUID
Step 5: Validate role metadata
验证role
Step 6: Service API request
请求service api
Step 7: Return response
得到结果
测试代码
Server.py
#!/usr/bin/env python
#*-*coding:utf-8*-*
"""Hello World using WebOb, Paste + WSGI """
from paste import httpserver
from paste.deploy import loadapp
INI_PATH = '/home/hugb/mycode/ae2/app/router/etc/ae2-paste.ini'
httpserver.serve(loadapp('config:' + INI_PATH), host='192.168.1.180', port=8089)
App.py
#!/usr/bin/env python
#*-*coding:utf-8*-*
from webob import Response
from webob.dec import wsgify
from webob import exc
class application:
def __init__(self, name, greeting):
self.name = name
self.greeting = greeting
def __call__(self, environ, start_response):
status = '200 OK'
response_headers = [('Content-Type', 'text/plain')]
start_response(status, response_headers)
return ['%s, %s!\n' % (self.greeting, self.name)]
def app_factory(global_config, name='Johnny', greeting='Howdy'):
return application(name, greeting)
def filter_factory(global_conf, **local_config):
conf = global_conf.copy()
conf.update(local_config)
def filter(app):
return AuthFilter(app, conf)
return filter
class AuthFilter(object):
def __init__(self, app, conf):
self.app = app
self.conf = conf
def __call__(self, environ, start_response):
if "HTTP_X_AUTH_TOKEN" in environ.keys():
return self.app(environ, start_response)
start_response('403 Forbidden', [('Content-type', 'text/html')])
return ['You are not set token']
ae2-paste.ini
[pipeline:main]
pipeline = auth authtoken ae2
[filter:auth]
paste.filter_factory = app:filter_factory
[app:ae2]
paste.app_factory = app:app_factory
[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
auth_host = 192.168.1.180
auth_port = 35357
auth_protocol = http
admin_tenant_name = ae2
admin_user = ae2
admin_password = admin
keystone --os-token keystone --os-endpoint http://192.168.1.180:35357/v2.0 user-list