在通過(guò)了keyStone驗(yàn)證通過(guò)后墩虹,openstack響應(yīng)endpoints數(shù)組反惕,這些數(shù)組對(duì)應(yīng)的是openstack的主要模塊訪問(wèn)地址齐邦,例如nova,neutron等憔四。
neutron:
{
"endpoints": [{
"region_id": "RegionOne",
"url": "http://xxx:9696",
"region": "RegionOne",
"interface": "internal",
"id": "1b6abf4194024a5a88ad536836918d34"
}, {
"region_id": "RegionOne",
"url": "http://xxx:9696",
"region": "RegionOne",
"interface": "admin",
"id": "8b7315fa74654cb8b86641bd44351da4"
}, {
"region_id": "RegionOne",
"url": "http://xxx:9696", // 這個(gè)就是可以通過(guò)外部訪問(wèn)的api更卒,http schema
"region": "RegionOne",
"interface": "public",
"id": "f895dc01a3424c1e955da86b7bdc63f2"
}],
"type": "network",
"id": "27c04c9ee6be457fa73671cf967aae19",
"name": "neutron"
}
在需要獲取network相關(guān)的api時(shí),就可以通過(guò)這個(gè)public的url進(jìn)行訪問(wèn)悬赏。
用戶就可以與openstack進(jìn)行交互查詢(xún)image丐吓,flavor,networks等數(shù)據(jù)柿汛,作為創(chuàng)建虛擬機(jī)的參數(shù)冗酿。
curl方式
在驗(yàn)證keystone的請(qǐng)求中埠对,需要加上參數(shù) -i ,這樣才能獲取返回的header(token在header中存放)裁替,x-Subject-Token
HTTP/1.1 201 Created
Date: Fri, 28 Oct 2016 09:22:22 GMT
Server: Apache
X-Subject-Token: gAAAAABYExjOa0G6p-5HkVwVxwFDJ7Dc_eXrkfGxQYUVF8sgD8WfQICNuQi76FAcQCvsayDPwiYGLOUQKjdmA2jA9FpGrmWWacBhn_fMbggN0gHAwkeWUrXg01JySJh7szvjHi0LqGo_OOY7NuJ34xpSPIp1A1sC__ETXvwpqMli9Va6JqqG8do
Vary: X-Auth-Token
x-openstack-request-id: req-4fbf6557-066b-4135-818e-cc935e45e313
Content-Length: 5407
Content-Type: application/json
為了方便測(cè)試项玛,可以將keystone驗(yàn)證返回的token和對(duì)應(yīng)的url存放在變量中,
export OS_TOKEN=gAAAAABYExjOa0G6p-5HkVwVxwFDJ7Dc_eXrkfGxQYUVF8sgD8WfQICNuQi76FAcQCvsayDPwiYGLOUQKjdmA2jA9FpGrmWWacBhn_fMbggN0gHAwkeWUrXg01JySJh7szvjHi0LqGo_OOY7NuJ34xpSPIp1A1sC__ETXvwpqMli9Va6JqqG8do
獲取flavors
curl -s -H "X-Auth-Token: $OS_TOKEN" \
$OS_COMPUTE_API/flavors \
| python -m json.tool
可以根據(jù)自己的需要從返回的配置中獲取flavor
{
"flavors": [
{
"id": "1",
"links": [
{
"href": "http://223.202.32.35:8774/v2.1/fc6ac8c46d8147fd9ffa7a32e373ff9a/flavors/1",
"rel": "self"
},
{
"href": "http://223.202.32.35:8774/fc6ac8c46d8147fd9ffa7a32e373ff9a/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny"
},
{
"id": "2",
"links": [
{
"href": "http://223.202.32.35:8774/v2.1/fc6ac8c46d8147fd9ffa7a32e373ff9a/flavors/2",
"rel": "self"
},
{
"href": "http://223.202.32.35:8774/fc6ac8c46d8147fd9ffa7a32e373ff9a/flavors/2",
"rel": "bookmark"
}
],
"name": "m1.small"
}
}
獲取image
curl -s -H "X-Auth-Token: $OS_TOKEN" \
$OS_IMAGE_API/v2/images \
| python -m json.tool
返回的json數(shù)據(jù)
{
"first": "/v2/images",
"images": [
{
"checksum": "0d7ba90f5923297ee53351ce7e72ab76",
"container_format": "bare",
"created_at": "2016-10-19T09:19:36Z",
"description": "",
"disk_format": "qcow2",
"file": "/v2/images/ea99659a-5109-49e3-9b0f-bf5345eb7d97/file",
"id": "ea99659a-5109-49e3-9b0f-bf5345eb7d97",
"min_disk": 10,
"min_ram": 512,
"name": "Centos 7",
"owner": "4f9cfde31f7d42f096b766e4b95855e8",
"protected": false,
"schema": "/v2/schemas/image",
"self": "/v2/images/ea99659a-5109-49e3-9b0f-bf5345eb7d97",
"size": 377880576,
"status": "active",
"tags": [],
"updated_at": "2016-10-26T08:56:33Z",
"virtual_size": null,
"visibility": "public"
}]
}
獲取networks信息
curl -s -H "X-Auth-Token: $OS_TOKEN" \
$OS_NETWORKS_API/v2.0/networks \
| python -m json.tool
返回的json弱判,其中在后面需要使用的一個(gè)是service襟沮,主要負(fù)責(zé)內(nèi)網(wǎng)ip的分配,另一個(gè)是public昌腰,進(jìn)行公網(wǎng)IP的分配
{
"networks": [
{
"admin_state_up": true,
"availability_zone_hints": [],
"availability_zones": [
"nova"
],
"created_at": "2016-10-08T07:09:20",
"description": "",
"id": "38d9d825-256b-4477-939b-42714a28776d",
"ipv4_address_scope": null,
"ipv6_address_scope": null,
"mtu": 1450,
"name": "HA network tenant 4f9cfde31f7d42f096b766e4b95855e8",
"port_security_enabled": true,
"provider:network_type": "vxlan",
"provider:physical_network": null,
"provider:segmentation_id": 9,
"router:external": false,
"shared": false,
"status": "ACTIVE",
"subnets": [
"2aea08cf-4027-4569-86b4-63646f6dd2b2"
],
"tags": [],
"tenant_id": "",
"updated_at": "2016-10-08T07:09:20"
},
{
"admin_state_up": true,
"availability_zone_hints": [],
"availability_zones": [
"nova"
],
"created_at": "2016-10-08T09:11:03",
"description": "",
"id": "baa3dbad-5994-4837-9263-32304ee7d035",
"ipv4_address_scope": null,
"ipv6_address_scope": null,
"is_default": false,
"mtu": 1500,
"name": "public",
"port_security_enabled": true,
"provider:network_type": "vlan",
"provider:physical_network": "vlan",
"provider:segmentation_id": 40,
"router:external": true,
"shared": true,
"status": "ACTIVE",
"subnets": [
"a2c44a10-6f23-42dd-b7d8-c3319d542628"
],
"tags": [],
"tenant_id": "4f9cfde31f7d42f096b766e4b95855e8",
"updated_at": "2016-10-08T09:19:18"
},
{
"admin_state_up": true,
"availability_zone_hints": [],
"availability_zones": [
"nova"
],
"created_at": "2016-10-09T04:04:29",
"description": "",
"id": "f3411c78-f02a-4556-9171-4e9e5b102b20",
"ipv4_address_scope": null,
"ipv6_address_scope": null,
"mtu": 1450,
"name": "service",
"port_security_enabled": true,
"provider:network_type": "vxlan",
"provider:physical_network": null,
"provider:segmentation_id": 71,
"router:external": false,
"shared": true,
"status": "ACTIVE",
"subnets": [
"a76d00f6-752a-40af-bbcd-fefb6a33fef0"
],
"tags": [],
"tenant_id": "4f9cfde31f7d42f096b766e4b95855e8",
"updated_at": "2016-10-10T05:43:49"
}
]
}
有了這些參數(shù)基本上就可以創(chuàng)建一個(gè)虛擬機(jī)實(shí)例了开伏。
curl -is -H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"server": {
"name": "patrick-vm",
"imageRef": "fff2aa1b-dd06-4dbf-b259-652057615f4b",
"flavorRef": "2",
"networks": [{"uuid": "f3411c78-f02a-4556-9171-4e9e5b102b20"}]
}}' \
$OS_COMPUTE_API/servers
如果需要采用keyPairs的方式登錄創(chuàng)建的虛擬機(jī)。添加參數(shù)key_name即可遭商,對(duì)應(yīng)的value就是秘鑰對(duì)的名字
如果需要在虛擬機(jī)創(chuàng)建后固灵,執(zhí)行相應(yīng)的腳本。則需要添加user_data這個(gè)參數(shù)劫流,腳本的編寫(xiě)方式需要滿足cloud-init要求巫玻,該參數(shù)填寫(xiě)前,需要將腳本編碼為base64格式困介。
添加參數(shù)后的請(qǐng)求如下:
curl -is -H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"server": {
"name": "patrick-vm",
"imageRef": "fff2aa1b-dd06-4dbf-b259-652057615f4b",
"flavorRef": "2",
"networks": [{"uuid": "f3411c78-f02a-4556-9171-4e9e5b102b20"}],
"user_data": "IyEvYmluL3NoIAplY2hvICJIZWxsbyBXb3JsZC4gIFRoZSB0aW1lIGlzIG5vdyAkKGRhdGUgLVIpISIgfCB0ZWUgL3Jvb3Qvb3V0cHV0LnR4dCAK",
"key_name": "op-key"
}}' \
$OS_COMPUTE_API/servers
其中user_data對(duì)應(yīng)的原文為
#!/bin/sh
echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt
pkgcloud
由于pkgcloud在createClient后將對(duì)應(yīng)的url和token都存放在client對(duì)象中大审,所以過(guò)程相對(duì)簡(jiǎn)單很多
var pkgcloud = require('pkgcloud'),
_ = require('lodash');
var cc = pkgcloud.compute.createClient({
provider: 'openstack', // required
username: '$user_name', // required
password: '$user_pass', // required
region: 'RegionOne',
keystoneAuthVersion: 'v3',
domainId: 'Default',
tenantId: 'fc6ac8c46d8147fd9ffa7a32e373ff9a',
domainName: 'Default',
authUrl: 'http://xxxx:5000' // required
});
var nc = pkgcloud.network.createClient({
provider: 'openstack', // required
username: '$user_name', // required
password: '$user_pass', // required
region: 'RegionOne',
keystoneAuthVersion: 'v3',
domainId: 'Default',
tenantId: 'fc6ac8c46d8147fd9ffa7a32e373ff9a',
domainName: 'Default',
authUrl: 'http://xxxx:5000' // required
});
cc.getFlavors(function(err, flavors) {
if (err) {
console.error(err);
return;
}
cc.getImages(function(err, images) {
if (err) {
console.log(err);
return;
}
var flavor = _.findWhere(flavors, { name: 'm1.small' });
var image = _.findWhere(images, { name: 'ubuntu14.04' });
var userData = '#!/bin/sh \n';
userData += 'echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt \n';
var userData64 = new Buffer(userData).toString("base64");
cc.createServer({
name: 'patrick_client',
image: image,
flavor: flavor,
networks: [{ uuid: 'f3411c78-f02a-4556-9171-4e9e5b102b20' }],
cloudConfig: userData64,
securityGroups: [{ name: 'default' }],
keyname: 'op-key'
}, handleServerResponse);
});
});
過(guò)程雖然比較簡(jiǎn)單,但是參數(shù)比較坑座哩,比如user_data的參數(shù)映射為了cloudConfig