OpenStack SDK 使用

OpenStack针对不同的用户提供4种与Python API交互的方式:

1)OpenStack SDK
2)Shadow
3)per-project libraries
4)直接通过RESTful调用keystoneauth

前提知识:
1)RESTful Web 服务
2)HTTP /1.1
3)JSON与数据序列化格式


1.OpenStack SDK

OpenStack Software Development Kit(OpenStack SDK),用于编写创建Python的自动化脚本,并在openstack中管理云资源。SDK实现了与OpenStack API 的Python绑定,使你能够通过调用Python对象来执行Python中的自动化任务,而不是直接使用REST调用。

新用户应该使用OpenStack SDK 来进行编码。

2.Shadow

Shadow是一个抽象库(就是没有实现的),专注于隐藏OpenStack云之间的实现差异。虽然OpenStack SDK向底层REST API提供了一个干净的对象接口,但如果这样做有利的话,阴影隐藏它们。如果您计划针对许多OpenStack云运行相同的Python程序,则可能需要使用阴影 - 但是如果您需要访问没有云中性抽象映射的云的任何功能,则无法执行此操作有阴影。

3.per-project libraries

每个OpenStack项目都会生成一个包装自己的REST API的客户端库。除非因某些原因没有其他选择,否则应避免每个项目库。

4.直接通过REST调用keystoneauth

所有OpenStack的API实际上都是REST API。
该 keystoneauth库提供了一个对象,它看起来非常像一个 会话从Python对象 请求库,处理所有身份验证的为您服务。
如果您更轻松地处理REST,或者如果您的云中实现了某项功能,但尚未在任何library中获得支持,则此选项适用于你。


安装OpenStack SDK

每个OpenStack项目都有自己的python库。
这些库命令与命令行客户机捆绑在一起。例如:compute API 的Python绑定与python-novaclient包捆绑在一起。

注意:项目的理解:
keystone 是一个项目 neutron是一个项目 nova使用一个项目 等等
keystone是你注册project


认证(Authenticate )

使用SDK时候,你必须先对OpenStack 的endpoint进行身份验证,然后才能使用OpenStack 服务。因为所有项目都使用keystone进行身份验证,所以无论你决定更使用哪种服务或者库,这个过程都是一样的。每个library都有更加先进和复杂的方式来做事情,如果有需要的话。

处理云配置和凭据有两种基本方法:
1)环境变量通过openrc.sh文件
2)clouds.yaml配置文件

环境变量已经是使用最久的,是您最有可能从云提供商那里获得的形式。如果您只有一个云端帐户,那么它们是最方便的方式。
clouds.yaml 是一个新的方式,旨在帮助有多个OpenStack云使用他们的人。

openrc.sh:里面存放的是环境变量。比如账号,密码等。


创建一个经典客户端对象

所有的传统客户端对象可以以相同的方式构造-唯一的区别是第一个参数make_client不同。
下面的例子可以使用compute 去获得一个nova client,但是neutron能够通过将compute改为network获得。

要使用具有Compute endpoint 的 python-novaclient,请使用下面的方法创建:

import os_client_config

nova = os_client_config.make_client(
    'compute',
    auth_url='https://example.com',
    username='example-openstack-user',
    password='example-password',
    project_name='example-project-name',
    region_name='example-region-name')

如果你想要一个特定的微型版本的Nova API,你可以把它作为version参数:

import os_client_config

nova = os_client_config.make_client(
    'compute',
    version='2.10',
    auth_url='https://example.com',
    username='example-openstack-user',
    password='example-password',
    project_name='example-project-name',
    region_name='example-region-name')

注意:nova client代表的是可以操作nova的相关功能。

如果对使用自定义身份验证endpoint进行身份验证,则必须在auth_type参数中提供插件的名称 。
例如,Rackspace公共云是具有可选的自定义身份验证后端的OpenStack部署。正常的梯形密码认证工作原理非常好,你可能希望使用rackspace-keystonauth-plugin中定制的rackspace keystoneauth API Key 插件。

nova = os_client_config.make_client(
    'compute',
    auth_type='rackspace_apikey',
    auth_url='https://example.com',
    username='example-openstack-user',
    api_key='example-apikey',
    project_name='example-project-name',
    region_name='example-region-name')

管理image

在使用SDK中的image的时候,你将调用glancenova

列出image:

import glanceclient.v2.client as glclient
glance = glclient.Client(...)
images = glance.images.list()

images方法返回一个python生成器(generator),如以下雨python解释器的交互所示:

>>> images = glance.images.list()
>>> images
<generator object list at 0x105e9c2d0>
>>> list(images)
[{u'checksum': u'f8a2eeee2dc65b3d9b6e63678955bd83',
  u'container_format': u'ami',
  u'created_at': u'2013-10-20T14:28:10Z',
  u'disk_format': u'ami',
  u'file': u'/v2/images/dbc9b2db-51d7-403d-b680-3f576380b00c/file',
  u'id': u'dbc9b2db-51d7-403d-b680-3f576380b00c',
  u'kernel_id': u'c002c82e-2cfa-4952-8461-2095b69c18a6',
  u'min_disk': 0,
  u'min_ram': 0,
  u'name': u'cirros-0.3.5-x86_64-uec',
  u'protected': False,
  u'ramdisk_id': u'4c1c9b4f-3fe9-425a-a1ec-1d8fd90b4db3',
  u'schema': u'/v2/schemas/image',
  u'size': 25165824,
  u'status': u'active',
  u'tags': [],
  u'updated_at': u'2013-10-20T14:28:11Z',
  u'visibility': u'public'},
 {u'checksum': u'69c33642f44ca552ba4bb8b66ad97e85',
  u'container_format': u'ari',
  u'created_at': u'2013-10-20T14:28:09Z',
  u'disk_format': u'ari',
  u'file': u'/v2/images/4c1c9b4f-3fe9-425a-a1ec-1d8fd90b4db3/file',
  u'id': u'4c1c9b4f-3fe9-425a-a1ec-1d8fd90b4db3',
  u'min_disk': 0,
  u'min_ram': 0,
  u'name': u'cirros-0.3.5-x86_64-uec-ramdisk',
  u'protected': False,
  u'schema': u'/v2/schemas/image',
  u'size': 3714968,
  u'status': u'active',
  u'tags': [],
  u'updated_at': u'2013-10-20T14:28:10Z',
  u'visibility': u'public'},
 {u'checksum': u'c352f4e7121c6eae958bc1570324f17e',
  u'container_format': u'aki',
  u'created_at': u'2013-10-20T14:28:08Z',
  u'disk_format': u'aki',
  u'file': u'/v2/images/c002c82e-2cfa-4952-8461-2095b69c18a6/file',
  u'id': u'c002c82e-2cfa-4952-8461-2095b69c18a6',
  u'min_disk': 0,
  u'min_ram': 0,
  u'name': u'cirros-0.3.5-x86_64-uec-kernel',
  u'protected': False,
  u'schema': u'/v2/schemas/image',
  u'size': 4955792,
  u'status': u'active',
  u'tags': [],
  u'updated_at': u'2013-10-20T14:28:09Z',
  u'visibility': u'public'}]

通过ID获得image

要从ID中检索出图像对象,请调用以下方法:

import glanceclient.v2.client as glclient
image_id = 'c002c82e-2cfa-4952-8461-2095b69c18a6'
glance = glclient.Client(...)
image = glance.images.get(image_id)

通过名字获得image:

image服务python绑定 不支持按名称检索image对象。然而,compute python 绑定(nova),可以让你通过名称获得Image对象。用通过名称获取Image对象,方法如下:

import novaclient.v2.client as nvclient
name = "cirros"
nova = nvclient.Client(...)
image = nova.images.find(name=name)

上传镜像:

import glanceclient.v2.client as glclient
imagefile = "/tmp/myimage.img"
glance = glclient.Client(...)
with open(imagefile) as fimage:
  glance.images.create(name="myimage", is_public=False, disk_format="qcow2",
                       container_format="bare", data=fimage)

将CORS header 分配给请求

跨原始资源共享 Cross-Origin Resource Sharing(CORS)
是一个贵方,用于定义浏览器和服务器如果通过使用HTTP headers(标头),例如由Object Storage API 请求分配的HTTP 头 进行通信。对象存储API支持以下headers:


调用对象为了删除:

要确定对象存储系统是否支持此功能,请参阅管理对象和容器。
计划要删除的对象有助于管理不想永久存储的对象,例如日志文件,数据集的定期备份,或者在指定时间过时的文档或者图像。
要安排一个要删除的对象,请在对象中包含这些头中的一个PUT或者POST 请求:

X-Delete-At

UNIX纪元的事件戳,是证书形式。例如:1348691905(时间戳)代表的是:Wed, 26 Sept 2012 20:38:25 GMT
它指定您希望对象到期的时间,不再被提供,并从对象存储完全删除。

X-Delete-After

就是请求之后,隔了这么多时间就删除。

注意:X-Delete-AtX-Delete-After都是请求头里面的参数。

使用POST方法将过期标头分配给要过期的现有对象。

下面的例子是执行之后在时间戳1390581073失效:

$ curl -i publicURL/marktwain/goodbye -X PUT -H "X-Auth-Token: token" \
  -H "X-Delete-At: 1390581073" -H "Content-Length: 14" -H \
  "Content-Type: application/octet-stream"

下面是经过864000久之后失效:

PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.example.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Type: image/jpeg
X-Delete-After: 864000

配置实例的访问和安全性

当使用SDK中的图像时,你将调用novaclient方法。

添加密钥对:

生成一个密钥对,可以调用:novaclient.v1_1.keypairs.KeypairManager.create 方法:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
keypair_name = "staging"
keypair = nova.keypairs.create(name=keypair_name)
print keypair.private_key

python脚本输出会是这样的:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA8XkaMqInSPfy0hMfWO+OZRtIgrQAbQkNcaNHmv2GN2G6xZlb\nuBRux5Xk/6SZ
ABaNPm1nRWm/ZDHnxCsFTcAl2LYOQXx3Cl2qKNY4r2di4G48GAkd\n7k5lDP2RgQatUM8npO0CD9PU
...
mmrceYYK08/lQ7JKLmVkdzdQKt77+v1oBBuHiykLfI6h1m77NRDw9r8cV\nzczYeoALifpjTPMkKS8
ECfDCuDn/vc9K1He8CRaJHf8AMLQLM3MN
-----END RSA PRIVATE KEY-----

你通常将私钥写入文件以便稍后使用。该文件只能由文件所有者读取和写入;否则,SSH客户端将拒绝读取私钥文件。最安全的方法是使用适当的权限创建文件:

import novaclient.v2.client as nvclient
import os
nova = nvclient.Client(...)
keypair_name = "staging"
private_key_filename = "/home/alice/id-staging"
keypair = nova.keypairs.create(name=keypair_name)

# Create a file for writing that can only be read and written by
owner
fp = os.open(private_key_filename, os.O_WRONLY | os.O_CREAT, 0o600)
with os.fdopen(fp, 'w') as f:
    f.write(keypair.private_key)

导入密钥对:

如果已经使用位于该公钥的密钥对生成了密钥对,则~/.ssh/id_rsa.pub将该文件的内容传递给novaclient.v1_1.keypairs.KeypairManager.create方法将公钥导入到Compute:

import novaclient.v2.client as nvclient
import os.path
with open(os.path.expanduser('~/.ssh/id_rsa.pub')) as f:
    public_key = f.read()
nova = nvclient.Client(...)
nova.keypairs.create('mykey', public_key)

列出密钥对:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
keypairs = nova.keypairs.list()

创建和管理安全组:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
security_groups = nova.security_groups.list()

创建具有指定名称和描述的安全组:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
nova.security_groups.create(name="web", description="Web servers")

删除安全组:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
group = nova.security_groups.find(name="web")
nova.security_groups.delete(group)
# The following lines would also delete the group:
# nova.security_groups.delete(group.id)
# group.delete()

创建和管理安全组角色:
查看安全组角色:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
group = nova.security_groups.find(name="web")
print group.rules

增加角色给安全组:

import novaclient.v2.client as nvclient
nova = nvclient.Client(...)
group = nova.security_groups.find(name="web")
# Add rules for ICMP, tcp/80 and tcp/443
nova.security_group_rules.create(group.id, ip_protocol="icmp",
                                 from_port=-1, to_port=-1)
nova.security_group_rules.create(group.id, ip_protocol="tcp",
                                 from_port=80, to_port=80)
nova.security_group_rules.create(group.id, ip_protocol="tcp",
                                 from_port=443, to_port=443)

网络

要理解用本节的信息,应该对OpenStack Networking,OpenStack Compute以及两者之间的集成有一个一般的了解。还应该可以访问实现Networking API v2.0的插件。

设置环境变量:

确保你设置相关的环境变量。

使用shell 文件设置以下的环境变量去获得凭证:

export OS_USERNAME="admin"
export OS_PASSWORD="password"
export OS_TENANT_NAME="admin"
export OS_AUTH_URL="http://IPADDRESS/v2.0"

获取凭证,本节中的示例使用以下的方法:

def get_credentials():
    d = {}
    d['username'] = os.environ['OS_USERNAME']
    d['password'] = os.environ['OS_PASSWORD']
    d['auth_url'] = os.environ['OS_AUTH_URL']
    d['tenant_name'] = os.environ['OS_TENANT_NAME']
    return d

就是一个字典,里面包含了环境信息。
上面的代码存在于credentials.py,都是被导入进来了的,
所以可以简单使用下面的方法获得字典:

nova_credentials = get_nova_credentials()

打印值:

def print_values(val, type):
    if type == 'ports':
        val_list = val['ports']
    if type == 'networks':
        val_list = val['networks']
    if type == 'routers':
        val_list = val['routers']
    for p in val_list:
        for k, v in p.items():
            print("%s : %s" % (k, v))
        print('\n')


def print_values_server(val, server_id, type):
    if type == 'ports':
        val_list = val['ports']

    if type == 'networks':
        val_list = val['networks']
    for p in val_list:
        bool = False
        for k, v in p.items():
            if k == 'device_id' and v == server_id:
                bool = True
        if bool:
            for k, v in p.items():
                print("%s : %s" % (k, v))
            print('\n')

上面的代码是存在于utils.py文件中,可以直接导入。

创建网络:

#!/usr/bin/env python
from neutronclient.v2_0 import client
from credentials import get_credentials

network_name = 'sample_network'
credentials = get_credentials()
neutron = client.Client(**credentials)
try:
    body_sample = {'network': {'name': network_name,
                   'admin_state_up': True}}

    netw = neutron.create_network(body=body_sample)
    net_dict = netw['network']
    network_id = net_dict['id']
    print('Network %s created' % network_id)

    body_create_subnet = {'subnets': [{'cidr': '192.168.199.0/24',
                          'ip_version': 4, 'network_id': network_id}]}

    subnet = neutron.create_subnet(body=body_create_subnet)
    print('Created subnet %s' % subnet)
finally:
    print("Execution completed")

列出网络:

#!/usr/bin/env python
from neutronclient.v2_0 import client
from credentials import get_credentials
from utils import print_values

credentials = get_credentials()
neutron = client.Client(**credentials)
netw = neutron.list_networks()

print_values(netw, 'networks')

创建端口:

#!/usr/bin/env python
from neutronclient.v2_0 import client
import novaclient.v2.client as nvclient
from credentials import get_credentials
from credentials import get_nova_credentials

credentials = get_nova_credentials()
nova_client = nvclient.Client(**credentials)

# Replace with server_id and network_id from your environment

server_id = '9a52795a-a70d-49a8-a5d0-5b38d78bd12d'
network_id = 'ce5d204a-93f5-43ef-bd89-3ab99ad09a9a'
server_detail = nova_client.servers.get(server_id)
print(server_detail.id)

if server_detail != None:
    credentials = get_credentials()
    neutron = client.Client(**credentials)

    body_value = {
                     "port": {
                             "admin_state_up": True,
                             "device_id": server_id,
                             "name": "port1",
                             "network_id": network_id
                      }
                 }
    response = neutron.create_port(body=body_value)
    print(response)

监听端口:

#!/usr/bin/env python
from neutronclient.v2_0 import client
from credentials import get_credentials
from utils import print_values

credentials = get_credentials()
neutron = client.Client(**credentials)
ports = neutron.list_ports()
print_values(ports, 'ports')

监听服务端口:

#!/usr/bin/env python
from neutronclient.v2_0 import client
import novaclient.v2.client as nvclient
from credentials import get_credentials
from credentials import get_nova_credentials
from utils import print_values_server

credentials = get_nova_credentials()
nova_client = nvclient.Client(**credentials)

# change these values according to your environment

server_id = '9a52795a-a70d-49a8-a5d0-5b38d78bd12d'
network_id = 'ce5d204a-93f5-43ef-bd89-3ab99ad09a9a'
server_detail = nova_client.servers.get(server_id)
print(server_detail.id)

if server_detail is not None:
    credentials = get_credentials()
    neutron = client.Client(**credentials)
    ports = neutron.list_ports()

    print_values_server(ports, server_id, 'ports')
    body_value = {'port': {
        'admin_state_up': True,
        'device_id': server_id,
        'name': 'port1',
        'network_id': network_id,
        }}

    response = neutron.create_port(body=body_value)
    print(response)

创建路由和给子网增加端口:

1)导入modules:

from neutronclient.v2_0 import client
import novaclient.v2.client as nvclient
from credentials import get_credentials
from credentials import get_nova_credentials
from utils import print_values_server

2)获得nova凭证,可以参考上面的。

3)创建nova_client实例:

nova_client = nvclient.Client(**credentials)

4)为子网创建路由和端口:

# Replace with network_id from your environment

network_id = '81bf592a-9e3f-4f84-a839-ae87df188dc1'

credentials = get_credentials()
neutron = client.Client(**credentials)
neutron.format = json
request = {'router': {'name': 'router name',
                      'admin_state_up': True}}

router = neutron.create_router(request)
router_id = router['router']['id']
# for example: '72cf1682-60a8-4890-b0ed-6bad7d9f5466'
router = neutron.show_router(router_id)
print(router)
body_value = {'port': {
    'admin_state_up': True,
    'device_id': router_id,
    'name': 'port1',
    'network_id': network_id,
    }}

response = neutron.create_port(body=body_value)
print(response)
print("Execution Completed")

创建路由:完整示例 :

#!/usr/bin/env python
from neutronclient.v2_0 import client
import novaclient.v2.client as nvclient
from credentials import get_credentials
from credentials import get_nova_credentials
from utils import print_values_server

credentials = get_nova_credentials()
nova_client = nvclient.Client(**credentials)

# Replace with network_id from your environment

network_id = '81bf592a-9e3f-4f84-a839-ae87df188dc1'
try:
    credentials = get_credentials()
    neutron = client.Client(**credentials)
    neutron.format = 'json'
    request = {'router': {'name': 'router name',
                          'admin_state_up': True}}
    router = neutron.create_router(request)
    router_id = router['router']['id']
    # for example: '72cf1682-60a8-4890-b0ed-6bad7d9f5466'
    router = neutron.show_router(router_id)
    print(router)
    body_value = {'port': {
        'admin_state_up': True,
        'device_id': router_id,
        'name': 'port1',
        'network_id': network_id,
        }}

    response = neutron.create_port(body=body_value)
    print(response)
finally:
    print("Execution completed")

删除网络:
1)导入模块:

from neutronclient.v2_0 import client
from credentials import get_credentials

2)获得凭证:Get Nova credentials.

3)创建实例:

neutron = client.Client(**credentials)

4)删除网络:

body_sample = {'network': {'name': network_name,
               'admin_state_up': True}}

netw = neutron.create_network(body=body_sample)
net_dict = netw['network']
network_id = net_dict['id']
print('Network %s created' % network_id)

body_create_subnet = {'subnets': [{'cidr': '192.168.199.0/24',
                      'ip_version': 4, 'network_id': network_id}]}

subnet = neutron.create_subnet(body=body_create_subnet)
print('Created subnet %s' % subnet)

neutron.delete_network(network_id)
print('Deleted Network %s' % network_id)

print("Execution completed")

完整示例:

#!/usr/bin/env python
from neutronclient.v2_0 import client
from credentials import get_credentials

network_name = 'temp_network'
credentials = get_credentials()
neutron = client.Client(**credentials)
try:
    body_sample = {'network': {'name': network_name,
                   'admin_state_up': True}}

    netw = neutron.create_network(body=body_sample)
    net_dict = netw['network']
    network_id = net_dict['id']
    print('Network %s created' % network_id)

    body_create_subnet = {'subnets': [{'cidr': '192.168.199.0/24',
                          'ip_version': 4, 'network_id': network_id}]}

    subnet = neutron.create_subnet(body=body_create_subnet)
    print('Created subnet %s' % subnet)

    neutron.delete_network(network_id)
    print('Deleted Network %s' % network_id)
finally:
    print("Execution Completed")

列出路由:
完整示例:

#!/usr/bin/env python
from neutronclient.v2_0 import client
from credentials import get_credentials
from utils import print_values

try:
    credentials = get_credentials()
    neutron = client.Client(**credentials)
    routers_list = neutron.list_routers(retrieve_all=True)
    print_values(routers_list, 'routers')
finally:
    print("Execution completed")

列出子网:

#!/usr/bin/env python
from neutronclient.v2_0 import client
from credentials import get_credentials
from utils import print_values

credentials = get_credentials()
neutron = client.Client(**credentials)
subnets = neutron.list_subnets()
print(subnets)

计算:

获得OpenStack凭证:

def get_nova_credentials_v2():
    d = {}
    d['version'] = '2'
    d['username'] = os.environ['OS_USERNAME']
    d['api_key'] = os.environ['OS_PASSWORD']
    d['auth_url'] = os.environ['OS_AUTH_URL']
    d['project_id'] = os.environ['OS_TENANT_NAME']
    return d

简单获取:

credentials = get_nova_credentials_v2()

列出服务:

#!/usr/bin/env python
from credentials import get_nova_credentials_v2
from novaclient.client import Client

credentials = get_nova_credentials_v2()
nova_client = Client(**credentials)

print(nova_client.servers.list())

创建server:

#!/usr/bin/env python
import time
from credentials import get_nova_credentials_v2
from novaclient.client import Client

try:
    credentials = get_nova_credentials_v2()
    nova_client = Client(**credentials)

    image = nova_client.images.find(name="cirros")
    flavor = nova_client.flavors.find(name="m1.tiny")
    net = nova_client.networks.find(label="private")
    nics = [{'net-id': net.id}]
    instance = nova_client.servers.create(name="vm2", image=image,
                                      flavor=flavor, key_name="keypair-1", nics=nics)
    print("Sleeping for 5s after create command")
    time.sleep(5)
    print("List of VMs")
    print(nova_client.servers.list())
finally:
    print("Execution Completed")

删除server:

#!/usr/bin/env python
from credentials import get_nova_credentials_v2
from novaclient.client import Client

credentials = get_nova_credentials_v2()
nova_client = Client(**credentials)

servers_list = nova_client.servers.list()
server_del = "vm1"
server_exists = False

for s in servers_list:
    if s.name == server_del:
        print("This server %s exists" % server_del)
        server_exists = True
        break
if not server_exists:
    print("server %s does not exist" % server_del)
else:
    print("deleting server..........")
    nova_client.servers.delete(s)
    print("server %s deleted" % server_del)

更新server:


#!/usr/bin/env python

from credentials import get_nova_credentials_v2
from novaclient.client import Client
from utils import print_server

credentials = get_nova_credentials_v2()
nova_client = Client(**credentials)

# Change the server_id specific to your environment

server_id = '99889c8d-113f-4a7e-970c-77f1916bfe14'
server = nova_client.servers.get(server_id)
n = server.name
print_server(server)

server.update(name=n +'1')
server_updated = nova_client.servers.get(server_id)
print_server(server_updated)

列出:

#!/usr/bin/env python

from credentials import get_nova_credentials_v2
from novaclient.client import Client
from utils import print_flavors

credentials = get_nova_credentials_v2()
nova_client = Client(**credentials)

flavors_list = nova_client.flavors.list()
print_flavors(flavors_list)

列出浮动ip:

#!/usr/bin/env python

from credentials import get_nova_credentials_v2
from novaclient.client import Client
from utils import print_values_ip

credentials = get_nova_credentials_v2()
nova_client = Client(**credentials)
ip_list = nova_client.floating_ips.list()
print_values_ip(ip_list)

列出hosts:

#!/usr/bin/env python

from credentials import get_nova_credentials_v2
from novaclient.client import Client
from utils import print_hosts

credentials = get_nova_credentials_v2()
nova_client = Client(**credentials)
host_list = nova_client.hosts.list()

print_hosts(host_list)

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值