pkgcloud和curl创建openstack实例.

在通过了keyStone验证通过后,openstack响应endpoints数组,这些数组对应的是openstack的主要模块访问地址,例如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", // 这个就是可以通过外部访问的api,http schema

         "region": "RegionOne",

         "interface": "public",

         "id": "f895dc01a3424c1e955da86b7bdc63f2"

     }],

     "type": "network",

     "id": "27c04c9ee6be457fa73671cf967aae19",

     "name": "neutron"

 }

在需要获取network相关的api时,就可以通过这个public的url进行访问。

用户就可以与openstack进行交互查询image,flavor,networks等数据,作为创建虚拟机的参数。

curl方式

在验证keystone的请求中,需要加上参数 -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

为了方便测试,可以将keystone验证返回的token和对应的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

可以根据自己的需要从返回的配置中获取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数据

{
    "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,其中在后面需要使用的一个是service,主要负责内网ip的分配,另一个是public,进行公网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"
        }
    ]
}

有了这些参数基本上就可以创建一个虚拟机实例了。

  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的方式登录创建的虚拟机。添加参数key_name即可,对应的value就是秘钥对的名字

如果需要在虚拟机创建后,执行相应的脚本。则需要添加user_data这个参数,脚本的编写方式需要满足cloud-init要求,该参数填写前,需要将脚本编码为base64格式。

添加参数后的请求如下:

 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对应的原文为

#!/bin/sh

echo "Hello World.  The time is now $(date -R)!" | tee /root/output.txt

pkgcloud

由于pkgcloud在createClient后将对应的url和token都存放在client对象中,所以过程相对简单很多

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);

    });

});

过程虽然比较简单,但是参数比较坑,比如user_data的参数映射为了cloudConfig

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容