Openstack REST API 调用开发入门
转载请注明出处:http://blog.csdn.net/jerry_liu20080504/article/details/65635201
访问Openstack的各个服务有REST API、DashBoard、Conmand Line等几种方式,几种访问方式大同小异。
本文将简单介绍三种访问方式(其中插件和java两种方式均是通过openstack rest api,只是语言选择不同)。本文是以我们的项目为依托写的,由于项目是以java方式开发的,所以本文可能更加侧重java访问方式
,其他只是为了辅助java。
我们的项目是想把Openstack DashBoard界面内容集成到自己的网站中。当时想到三种方式,第一种是整体迁移DashBoard集成到我们网站中,但未发现有效方法。第二种是通过openstack rest api(通过java访问)
获取类dashboard中的数据(之所以说是类dashboard的数据,是因为dashboard中的某些数据通过openstach rest api无法获取到的)。第三种是通过直接访问openstack的数据库获取数据(但分析认为某些实时运行
的数据很可能取不到)。最终我们选择了第二种方式,通过我们网站的后端利用java语言调用openstack rest api来获取数据之后将这些数据照dashboard界面的样式展示在前端(某些数据如果实在无法获取如果可能
的话考虑通过直接访问openstack数据库来获取)。
三种方式中DashBoard方式是相对固定的,几乎无法进行二次开发,只作为我们开发网页时照猫画虎。openstack rest api调用支持很多种语言,java只是其中一种。支持java的库也有很多种,比如apache jclouds、
openstack4j、httpclient等等。比较后我们选择了openstack4j。但是由于openstack和openstack4j版本问题,在利用openstack4j开发的时候会遇到很多问题,比如某些数据获取不到或者某些属性根本在
openstack4j的api列表中根本没有。openstack4j本身对底层调试信息的打印支持度不高,而此时同样的数据可能通过其他rest api“调用实现”比如RESTClient插件能获取到,而且能看到网络底层打印信息。所以我
们选择了RESTClient来进行辅助开发。总结起来,我们开发的时候需要DashBoard照猫画虎,openstack4j是用到的主要库,RESTClient是辅助调试。
开发之前介绍几个重要的网址:
openstack官网
https://developer.openstack.org
万变不离其宗,这是最根本的参考网址。
OpenStack API Documentation
https://developer.openstack.org/api-guide/quick-start/
查询openstack rest api的最重要的网址,这里面只是一个目录,里面包含openstack各个服务对应的接口,比如:compute API(对应Navo服务),Identity API(对应KeyStone服务),Networking API(对应Neutron
服务)等。开发时重点参考。
http://www.openstack4j.com/
openstack4j官网。
http://www.openstack4j.com/learn
openstack4j接口介绍及实例,学习openstack4j的入门级教程。
http://www.openstack4j.com/javadoc/
openstack4j javadoc,类列表。
https://github.com/ContainX/openstack4j/issues
openstack4j的issues,有问题可以在这里检索,重点参考网址。
开发之初想快速调试api,查看api是否好使,最快看到调用api返回的正确信息才是最兴奋的。DashBoard通过填写域、用户名、密码即可登录进而浏览里面所有的信息,没有太多可介绍的东西。编写java程序调用
Openstack4j库又较慢。所以,我们选择最便捷的手段,通过插件填写一些简单的登录验证信息来获取信息,验证openstack平台好使之后再进行java开发。
自然地首先介绍利用火狐浏览器安装的RESTClient插件来进行调试的方式,步骤如下:
1.下载火狐浏览器并且安装插件RESTClient插件(以下简称插件)。
2.通过插件调试Openstack REST API。
下面通过调试例子介绍整个调试过程。
调试例子1:
OpenStack身份验证调试,通过用户id和密码及Project id获取获取访问各个服务的token。对应的服务为KeyStone,对应Identity API,网页为:Identity API v3 (CURRENT),
https://developer.openstack.org/api-ref/identity/v3/
身份验证鉴权有很多方式,主要是参数的不同,我们这里选择的是“/v3/auth/tokens”中的Password authentication with scoped authorization方式。
在火狐浏览器插件界面上:
Method:POST。值在界面下拉列表中选择。
URL:http://XX.XX.XX.XX:5000/v3/auth/tokens。手动填写,其中的地址和端口可以通过Openstack DashBoard(Openstack网页版管理入口,对应Horizon服务)中的项目->计算->访问&安全->访问API(列表)中的
服务和服务端点查找。如果服务端点中的地址不是以ip形式给出或者以内网ip形式给出,可以尝试使用DashBoard的地址。端口号后面的网址是根据服务的不同和版本不同有所差异的,最好严格按照服务端点列表中的
地址进行调试。
Headers:在插件界面的顶部Headers列表中新建或者选择Header Name为Content-Type的Header,Header Value填写application/json,代表POST给openstack服务器的数据格式是json格式的。
Body:填写json格式的请求数据。参考前面提到的Identity api中的网址/v3/auth/tokens中提到的一种方式Password authentication with scoped authorization方式。(当然还可以通过其他几种方式进行身份验
证)
json格式的请求数据如下:
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"id": "1e0f6fc35cdb4aac82741a259470b2e4",
"password": "Neu"
}
}
},
"scope": {
"project": {
"id": "d65c0ead45594d0d8fc3e3eace892ba7"
}
}
}
}
其中id即登录DashBoard的用户名对应的id(DashBoard登录之后的身份管理->用户列表中可以查到),密码就是登录DashBoard的密码。project id也是通过DashBoard中的身份管理->项目列表中查找。Openstack V3
开始需要在鉴权的时候scope到一个Project上,否则没有权限访问服务。
填写完以上信息之后就可以点击SEND按钮向Openstack的keystone发送请求进行身份验证了。正确和错误信息都可以参考前述鉴权api网址https://developer.openstack.org/api-ref/identity/v3/中每个服务url对应
的detail进行分析。
我们的例子成功的话,在插件界面下半部分的Response部分的Response Header中的Status code里会返回201 Created,代码代表响应状态,每个状态都有一个代码对应,这些在detail里都有介绍,建议仔细看detail
。我们重点关注的是Status Code和X-Subject-Token。X-Subject-Token对应的值就是我们要的token,值例如:
gAAAAABYpqgsXhZ1Tce4S_kgoRE22f857oU5CJZY27t2CXOKn1UMmzDN1zfzRpqNosLaP_SS7Azqfo0VniTRRrzYU_r48DylxzO3lIpZkH2_3lw2Kc0a-mYuXLiB6opXU4FtGpzKrOc6hX7Avp78L8HFrWirMaxJ_eMUPLbwXSgxcYW31ftHT0k。这个
token是后面调试每个具体服务的时候每次请求都必须要带的。
上述过程对应的openstack4j中的Identity (Keystone) V3鉴权过程。具体http://www.openstack4j.com/learn中的Identity (Keystone) V3。
java工程的搭建参考openstack4j官网中的介绍,采用maven方式。不细介绍。
对应java代码为:
OSClientV3 os = OSFactory.builderV3()
.withConfig(Config.newConfig().withEndpointURLResolver(endpointUrlResolver))
.endpoint("http://XX.XX.XX.XX:5000/v3").credentials("admin", "Neu", Identifier.byName("default"))
.scopeToProject(Identifier.byName("admin"), Identifier.byName("default")).perspective(Facing.PUBLIC)
.authenticate();
代码里用到的withEndpointURLResolver(endpointUrlResolver))可视情况用,后文有相关介绍。
这里需要说明一下,在整个openstack系统中,用户名不是唯一的,用户id是唯一的,域名(domain name)是唯一的。project id是唯一的,project名不是唯一的。但是域名+用户名可以唯一确定一个用户,域名
+project名可以唯一确定project。所以,利用用户id登录等同于利用域名+用户名登录,同理对project也是一样。
身份验证鉴权通过之后,获取token之后,就可以利用这个token访问其他服务了。例如获取所有服务器列表(服务器即虚拟机、云主机、instance):
对应openstack rest api为:
http://XX.XX.XX.XX:8774/{版本}/{Project id}/servers
例如:http://XX.XX.XX.XX:8774/v2.1/d65c0ead45594d0d8fc3e3eace892ba7/servers,这里的project id与身份验证时的一致。同样可以通过DashBoard中的项目->计算->访问&安全->服务端点获取。
具体在插件界面操作如下:
Method中选择GET。
URL:http://XX.XX.XX.XX:8774/v2.1/d65c0ead45594d0d8fc3e3eace892ba7/servers
Headers新建或者选择X-Auth-Token,Header Value填写我们鉴权时候获取的token,由于插件原因token码中间可能存在空格,如果有注意去掉(由于这个空格,我们在调试之初曾经悲催过很多次)。Header Value可
以直接写字符串,不用外加{}。
上述过程对应的openstack4j中的compute(Nova)服务。具体参见:Compute Service (Nova) http://www.openstack4j.com/learn/compute。
对应的代码为:
OSClientV3 os = OSFactory.builderV3()
.withConfig(Config.newConfig().withEndpointURLResolver(endpointUrlResolver))
.endpoint("http://XX.XX.XX.XX:5000/v3")
.credentials("admin", "Neusoft", Identifier.byName("default"))
.scopeToProject(Identifier.byName("admin"), Identifier.byName("default")).perspective(Facing.PUBLIC)
.authenticate();
List extends Server> servers = os.compute().servers().list();
其他服务依照获取服务器列表的例子,参见openstack和openstack4j官网给出的说明即可。
另外注意,在获取服务访问点的时候,由于openstack平台配置问题造成服务访问点返回的网址可能是http://controller:XXX/.../...形式,也即主机地址不是ip地址而是一个叫controller的地址,而这个地址dns无
法解析。这时候就需要用到openstack4j官网中http://www.openstack4j.com/learn/getting-started提到的Endpoint URL Resolver即自定义findURLV3函数。在程序的main函数里添加如下代码即可:
final EndpointURLResolver endpointUrlResolver = new EndpointURLResolver() {
@Override
public String findURLV2(URLResolverParams params) {
// TODO Auto-generated method stub
return null;
}
@Override
public String findURLV3(URLResolverParams params) {
switch (params.type.getServiceName()) {
case "keystone":
return "http://XX.XX.XX.XX:5000/v3";
case "glance":
return "http://XX.XX.XX.XX:9292";// 镜像服务,经openstack4j检验用的是v1版本
case "nova":
return "http://XX.XX.XX.XX:8774/v2.1/d65c0ead45594d0d8fc3e3eace892ba7";// compute计算相关
case "neutron":
return "http://XX.XX.XX.XX:9696";
case "cinder":
return "http://XX.XX.XX.XX:8776/v1/d65c0ead45594d0d8fc3e3eace892ba7";// 块存储经openstack4j检验用的是v1版本
default:
return null;
}
}
};
OSClientV3 os = OSFactory.builderV3()
.withConfig(Config.newConfig().withEndpointURLResolver(endpointUrlResolver))
.endpoint("http://XX.XX.XX.XX:5000/v3")
.credentials("admin", "Neu", Identifier.byName("default"))
.scopeToProject(Identifier.byName("admin"), Identifier.byName("default")).perspective(Facing.PUBLIC)
.authenticate();
鉴权的时候调用withConfig,选择自定义的endpointurlresover。
这里注意,我们之前的鉴权和获取服务器列表两个例子都使用了自定义的endpointurlresover。如果主机返回的是ip地址或者是dns可解析的主机地址,则不必使用自定义的endpointurlresover。
依照DashBoard照猫画虎的话,尽量选择英文版的画,中文翻译的东西容易造成歧义,很是影响开发。
Openstack4j开发的时候,要打印调试信息的话,OSFactory.enableHttpLoggingFilter(true);在使用connector为Jersey2 (openstack4j-jersey2)好使。Openstack4j 3.0.0版使用的是Jersey2。而从3.0.1到3.0.4
使用的都是resteasy(openstack4j-resteasy),所以该功能失效。
参考网址:
1.OpenStack REST API使用
http://www.tuicool.com/articles/qieArqi
2.通过Rest API调用OpenStack
http://blog.csdn.net/cnyyx/article/details/43836343
3.keystone v3 API的新特征
http://blog.chinaunix.net/uid-21335514-id-3497996.html
4.OpenStack之各组件介绍
http://www.mamicode.com/info-detail-220793.html
5.Openstack入坑指南
http://www.cnblogs.com/resn/p/5870264.html
6.OpenStack的版本演进和包含组件
http://f.dataguru.cn/thread-526221-1-1.html
7.OpenStack微讲堂系列09|创建虚拟机所需资源介绍
http://www.shuotoutiao.com/p/23brNgc.html
8.《OpenStack技术原理与实战》西安电子科技大学出版社 韩璞 2016年4月第1版 2016年4月第1次印刷