Add extension to allow hiding of addresses

* Servers in certain states will have network_info but it may change,
  (eg. rescheduled build on another host). The extension allows the
  operator to hide the address information in those states
* Fixes bug LP 1089092

Change-Id: Ie843e34a41c77903b201b45c5b67a6f75334cb5e
This commit is contained in:
Jason Kölker 2012-12-11 15:12:29 -06:00
parent 276fded497
commit b3bbd09131
29 changed files with 705 additions and 2 deletions

View File

@ -248,6 +248,14 @@
"namespace": "http://docs.openstack.org/compute/ext/fping/api/v1.1",
"updated": "2012-07-06T00:00:00+00:00"
},
{
"alias": "os-hide-server-addresses",
"description": "Support hiding server addresses in certain states.",
"links": [],
"name": "HideServerAddresses",
"namespace": "http://docs.openstack.org/compute/ext/hide_server_addresses/api/v1.1",
"updated": "2012-12-11T00:00:00+00:00"
},
{
"alias": "os-hosts",
"description": "Admin-only host administration",

View File

@ -107,6 +107,9 @@
<extension alias="os-fping" updated="2012-07-06T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/fping/api/v1.1" name="Fping">
<description>Fping Management Extension.</description>
</extension>
<extension alias="os-hide-server-addresses" updated="2012-12-11T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/hide_server_addresses/api/v1.1" name="HideServerAddresses">
<description>Support hiding server addresses in certain states.</description>
</extension>
<extension alias="os-hosts" updated="2011-06-29T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/hosts/api/v1.1" name="Hosts">
<description>Admin-only host administration</description>
</extension>

View File

@ -0,0 +1,54 @@
{
"server": {
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"addr": "192.168.0.3",
"version": 4
}
]
},
"created": "2012-12-19T20:32:40Z",
"flavor": {
"id": "1",
"links": [
{
"href": "http://openstack.example.com/openstack/flavors/1",
"rel": "bookmark"
}
]
},
"hostId": "d2697421d9869915ee376575508fdba76432f9b3ef451e7a1f86c62e",
"id": "2e9157dc-deea-4ee7-820a-640ecba32b5a",
"image": {
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
"links": [
{
"href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "http://openstack.example.com/v2/openstack/servers/2e9157dc-deea-4ee7-820a-640ecba32b5a",
"rel": "self"
},
{
"href": "http://openstack.example.com/openstack/servers/2e9157dc-deea-4ee7-820a-640ecba32b5a",
"rel": "bookmark"
}
],
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"progress": 0,
"status": "ACTIVE",
"tenant_id": "openstack",
"updated": "2012-12-19T20:32:42Z",
"user_id": "fake"
}
}

View File

@ -0,0 +1,19 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" status="ACTIVE" updated="2012-12-19T20:32:39Z" hostId="4ae230cb1f554a4a4e02b03bc79c2da5354c3051a70cef6298ace888" name="new-server-test" created="2012-12-19T20:32:37Z" userId="fake" tenantId="openstack" accessIPv4="" accessIPv6="" progress="0" id="b8b02dd4-b2bb-441d-b52a-ee5c89c832d2">
<image id="70a599e0-31e7-49b7-b260-868f441e862b">
<atom:link href="http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="bookmark"/>
</image>
<flavor id="1">
<atom:link href="http://openstack.example.com/openstack/flavors/1" rel="bookmark"/>
</flavor>
<metadata>
<meta key="My Server Name">Apache1</meta>
</metadata>
<addresses>
<network id="private">
<ip version="4" addr="192.168.0.3"/>
</network>
</addresses>
<atom:link href="http://openstack.example.com/v2/openstack/servers/b8b02dd4-b2bb-441d-b52a-ee5c89c832d2" rel="self"/>
<atom:link href="http://openstack.example.com/openstack/servers/b8b02dd4-b2bb-441d-b52a-ee5c89c832d2" rel="bookmark"/>
</server>

View File

@ -0,0 +1,16 @@
{
"server": {
"adminPass": "c47PrLGGmARP",
"id": "1130fd6e-4d52-4e2a-848f-89b28fa03a7a",
"links": [
{
"href": "http://openstack.example.com/v2/openstack/servers/1130fd6e-4d52-4e2a-848f-89b28fa03a7a",
"rel": "self"
},
{
"href": "http://openstack.example.com/openstack/servers/1130fd6e-4d52-4e2a-848f-89b28fa03a7a",
"rel": "bookmark"
}
]
}
}

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="cc81aaca-5c3c-4ac6-bffe-79eb7a12def2" adminPass="4Z9kWS2YcY9f">
<metadata/>
<atom:link href="http://openstack.example.com/v2/openstack/servers/cc81aaca-5c3c-4ac6-bffe-79eb7a12def2" rel="self"/>
<atom:link href="http://openstack.example.com/openstack/servers/cc81aaca-5c3c-4ac6-bffe-79eb7a12def2" rel="bookmark"/>
</server>

View File

@ -0,0 +1,56 @@
{
"servers": [
{
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"addr": "192.168.0.3",
"version": 4
}
]
},
"created": "2012-12-19T20:32:37Z",
"flavor": {
"id": "1",
"links": [
{
"href": "http://openstack.example.com/openstack/flavors/1",
"rel": "bookmark"
}
]
},
"hostId": "11c1ae0bb109cd0467c62e96917cfa2956a9f3c1dce9a6565d80f5eb",
"id": "625a1d37-3515-49ad-91e2-21075a1b2ccf",
"image": {
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
"links": [
{
"href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "http://openstack.example.com/v2/openstack/servers/625a1d37-3515-49ad-91e2-21075a1b2ccf",
"rel": "self"
},
{
"href": "http://openstack.example.com/openstack/servers/625a1d37-3515-49ad-91e2-21075a1b2ccf",
"rel": "bookmark"
}
],
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"progress": 0,
"status": "ACTIVE",
"tenant_id": "openstack",
"updated": "2012-12-19T20:32:39Z",
"user_id": "fake"
}
]
}

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
<servers xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server status="ACTIVE" updated="2012-12-19T20:32:42Z" hostId="120a7c150d2ad92ce84590d0780c67b9e8be59b7084d0bc292ec0378" name="new-server-test" created="2012-12-19T20:32:40Z" userId="fake" tenantId="openstack" accessIPv4="" accessIPv6="" progress="0" id="55db7849-8ec4-46dd-8897-492d82282f29">
<image id="70a599e0-31e7-49b7-b260-868f441e862b">
<atom:link href="http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="bookmark"/>
</image>
<flavor id="1">
<atom:link href="http://openstack.example.com/openstack/flavors/1" rel="bookmark"/>
</flavor>
<metadata>
<meta key="My Server Name">Apache1</meta>
</metadata>
<addresses>
<network id="private">
<ip version="4" addr="192.168.0.3"/>
</network>
</addresses>
<atom:link href="http://openstack.example.com/v2/openstack/servers/55db7849-8ec4-46dd-8897-492d82282f29" rel="self"/>
<atom:link href="http://openstack.example.com/openstack/servers/55db7849-8ec4-46dd-8897-492d82282f29" rel="bookmark"/>
</server>
</servers>

View File

@ -0,0 +1,18 @@
{
"servers": [
{
"id": "120eed64-e7db-409c-b565-38ce2bc90021",
"links": [
{
"href": "http://openstack.example.com/v2/openstack/servers/120eed64-e7db-409c-b565-38ce2bc90021",
"rel": "self"
},
{
"href": "http://openstack.example.com/openstack/servers/120eed64-e7db-409c-b565-38ce2bc90021",
"rel": "bookmark"
}
],
"name": "new-server-test"
}
]
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<servers xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server name="new-server-test" id="7c3e9b55-f06c-499b-9d72-266e7806ce5a">
<atom:link href="http://openstack.example.com/v2/openstack/servers/7c3e9b55-f06c-499b-9d72-266e7806ce5a" rel="self"/>
<atom:link href="http://openstack.example.com/openstack/servers/7c3e9b55-f06c-499b-9d72-266e7806ce5a" rel="bookmark"/>
</server>
</servers>

View File

@ -54,6 +54,7 @@
"compute_extension:floating_ips_bulk": "rule:admin_api",
"compute_extension:fping": "",
"compute_extension:fping:all_tenants": "rule:admin_api",
"compute_extension:hide_server_addresses": "is_admin:False",
"compute_extension:hosts": "rule:admin_api",
"compute_extension:hypervisors": "rule:admin_api",
"compute_extension:instance_usage_audit_log": "rule:admin_api",

View File

@ -0,0 +1,89 @@
# Copyright 2012 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Extension for hiding server addresses in certain states."""
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.compute import vm_states
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
opts = [
cfg.ListOpt('osapi_hide_server_address_states',
default=[vm_states.BUILDING],
help='List of instance states that should hide network info'),
]
CONF = cfg.CONF
CONF.register_opts(opts)
LOG = logging.getLogger(__name__)
authorize = extensions.soft_extension_authorizer('compute',
'hide_server_addresses')
class Controller(wsgi.Controller):
def __init__(self, *args, **kwargs):
super(Controller, self).__init__(*args, **kwargs)
hidden_states = CONF.osapi_hide_server_address_states
# NOTE(jkoelker) _ is not considered uppercase ;)
valid_vm_states = [getattr(vm_states, state)
for state in dir(vm_states)
if state.isupper()]
self.hide_address_states = [state.lower()
for state in hidden_states
if state in valid_vm_states]
def _perhaps_hide_addresses(self, instance, resp_server):
if instance.get('vm_state') in self.hide_address_states:
resp_server['addresses'] = {}
@wsgi.extends
def show(self, req, resp_obj, id):
resp = resp_obj
if not authorize(req.environ['nova.context']):
return
if 'server' in resp.obj and 'addresses' in resp.obj['server']:
instance = req.get_db_instance(id)
self._perhaps_hide_addresses(instance, resp.obj['server'])
@wsgi.extends
def detail(self, req, resp_obj):
resp = resp_obj
if not authorize(req.environ['nova.context']):
return
for server in list(resp.obj['servers']):
if 'addresses' in server:
instance = req.get_db_instance(server['id'])
self._perhaps_hide_addresses(instance, server)
class Hide_server_addresses(extensions.ExtensionDescriptor):
"""Support hiding server addresses in certain states."""
name = 'HideServerAddresses'
alias = 'os-hide-server-addresses'
namespace = ('http://docs.openstack.org/compute/ext/'
'hide_server_addresses/api/v1.1')
updated = '2012-12-11T00:00:00+00:00'
def get_controller_extensions(self):
return [extensions.ControllerExtension(self, 'servers', Controller())]

View File

@ -0,0 +1,151 @@
# Copyright 2012 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import itertools
from lxml import etree
import webob
from nova.api.openstack import wsgi
from nova import compute
from nova.compute import vm_states
from nova import exception
from nova.openstack.common import jsonutils
from nova import test
from nova.tests.api.openstack import fakes
SENTINEL = object()
def fake_compute_get(*args, **kwargs):
def _return_server(*_args, **_kwargs):
return fakes.stub_instance(*args, **kwargs)
return _return_server
class HideServerAddressesTest(test.TestCase):
content_type = 'application/json'
def setUp(self):
super(HideServerAddressesTest, self).setUp()
fakes.stub_out_nw_api(self.stubs)
self.flags(
osapi_compute_extension=[
'nova.api.openstack.compute.contrib.select_extensions'],
osapi_compute_ext_list=['Hide_server_addresses'])
def _make_request(self, url):
req = webob.Request.blank(url)
req.headers['Accept'] = self.content_type
res = req.get_response(fakes.wsgi_app(init_only=('servers',)))
return res
@staticmethod
def _get_server(body):
return jsonutils.loads(body).get('server')
@staticmethod
def _get_servers(body):
return jsonutils.loads(body).get('servers')
@staticmethod
def _get_addresses(server):
return server.get('addresses', SENTINEL)
def _check_addresses(self, addresses, exists):
self.assertTrue(addresses is not SENTINEL)
if exists:
self.assertTrue(addresses)
else:
self.assertFalse(addresses)
def test_show_hides_in_building(self):
instance_id = 1
uuid = fakes.get_fake_uuid(instance_id)
self.stubs.Set(compute.api.API, 'get',
fake_compute_get(instance_id, uuid=uuid,
vm_state=vm_states.BUILDING))
res = self._make_request('/v2/fake/servers/%s' % uuid)
self.assertEqual(res.status_int, 200)
server = self._get_server(res.body)
addresses = self._get_addresses(server)
self._check_addresses(addresses, exists=False)
def test_show(self):
instance_id = 1
uuid = fakes.get_fake_uuid(instance_id)
self.stubs.Set(compute.api.API, 'get',
fake_compute_get(instance_id, uuid=uuid,
vm_state=vm_states.ACTIVE))
res = self._make_request('/v2/fake/servers/%s' % uuid)
self.assertEqual(res.status_int, 200)
server = self._get_server(res.body)
addresses = self._get_addresses(server)
self._check_addresses(addresses, exists=True)
def test_detail_hides_building_server_addresses(self):
instance_0 = fakes.stub_instance(0, uuid=fakes.get_fake_uuid(0),
vm_state=vm_states.ACTIVE)
instance_1 = fakes.stub_instance(1, uuid=fakes.get_fake_uuid(1),
vm_state=vm_states.BUILDING)
instances = [instance_0, instance_1]
def get_all(*args, **kwargs):
return instances
self.stubs.Set(compute.api.API, 'get_all', get_all)
res = self._make_request('/v2/fake/servers/detail')
self.assertEqual(res.status_int, 200)
servers = self._get_servers(res.body)
self.assertEqual(len(servers), len(instances))
for instance, server in itertools.izip(instances, servers):
addresses = self._get_addresses(server)
exists = (instance['vm_state'] == vm_states.ACTIVE)
self._check_addresses(addresses, exists=exists)
def test_no_instance_passthrough_404(self):
def fake_compute_get(*args, **kwargs):
raise exception.InstanceNotFound()
self.stubs.Set(compute.api.API, 'get', fake_compute_get)
res = self._make_request('/v2/fake/servers/' + fakes.get_fake_uuid())
self.assertEqual(res.status_int, 404)
class HideAddressesXmlTest(HideServerAddressesTest):
content_type = 'application/xml'
@staticmethod
def _get_server(body):
return etree.XML(body)
@staticmethod
def _get_servers(body):
return etree.XML(body).getchildren()
@staticmethod
def _get_addresses(server):
addresses = server.find('{%s}addresses' % wsgi.XMLNS_V11)
if addresses is None:
return SENTINEL
return addresses

View File

@ -130,6 +130,7 @@ policy_data = """
"compute_extension:floating_ips_bulk": "",
"compute_extension:fping": "",
"compute_extension:fping:all_tenants": "is_admin:True",
"compute_extension:hide_server_addresses": "",
"compute_extension:hosts": "",
"compute_extension:hypervisors": "",
"compute_extension:instance_usage_audit_log": "",

View File

@ -240,6 +240,14 @@
"namespace": "http://docs.openstack.org/compute/ext/floating_ips_bulk/api/v2",
"updated": "%(timestamp)s"
},
{
"alias": "os-hide-server-addresses",
"description": "Support hiding server addresses in certain states.",
"links": [],
"name": "HideServerAddresses",
"namespace": "http://docs.openstack.org/compute/ext/hide_server_addresses/api/v1.1",
"updated": "2012-12-11T00:00:00+00:00"
},
{
"alias": "os-hosts",
"description": "%(text)s",

View File

@ -90,6 +90,9 @@
<extension alias="os-floating-ips-bulk" name="FloatingIpsBulk" namespace="http://docs.openstack.org/compute/ext/floating_ips_bulk/api/v2" updated="2012-10-29T13:25:27-06:00">
<description>%(text)s</description>
</extension>
<extension alias="os-hide-server-addresses" updated="2012-12-11T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/hide_server_addresses/api/v1.1" name="HideServerAddresses">
<description>Support hiding server addresses in certain states.</description>
</extension>
<extension alias="os-hosts" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/hosts/api/v1.1" name="Hosts">
<description>%(text)s</description>
</extension>

View File

@ -0,0 +1,54 @@
{
"server": {
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"addr": "%(ip)s",
"version": 4
}
]
},
"created": "%(timestamp)s",
"flavor": {
"id": "1",
"links": [
{
"href": "%(host)s/openstack/flavors/1",
"rel": "bookmark"
}
]
},
"hostId": "%(hostid)s",
"id": "%(id)s",
"image": {
"id": "%(uuid)s",
"links": [
{
"href": "%(host)s/openstack/images/%(uuid)s",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "%(host)s/v2/openstack/servers/%(id)s",
"rel": "self"
},
{
"href": "%(host)s/openstack/servers/%(id)s",
"rel": "bookmark"
}
],
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"progress": 0,
"status": "ACTIVE",
"tenant_id": "openstack",
"updated": "%(timestamp)s",
"user_id": "fake"
}
}

View File

@ -0,0 +1,19 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" status="ACTIVE" updated="%(timestamp)s" hostId="%(hostid)s" name="new-server-test" created="%(timestamp)s" userId="fake" tenantId="openstack" accessIPv4="" accessIPv6="" progress="0" id="%(id)s">
<image id="%(uuid)s">
<atom:link href="%(host)s/openstack/images/%(uuid)s" rel="bookmark"/>
</image>
<flavor id="1">
<atom:link href="%(host)s/openstack/flavors/1" rel="bookmark"/>
</flavor>
<metadata>
<meta key="My Server Name">Apache1</meta>
</metadata>
<addresses>
<network id="private">
<ip version="4" addr="%(ip)s"/>
</network>
</addresses>
<atom:link href="%(host)s/v2/openstack/servers/%(id)s" rel="self"/>
<atom:link href="%(host)s/openstack/servers/%(id)s" rel="bookmark"/>
</server>

View File

@ -0,0 +1,16 @@
{
"server" : {
"name" : "new-server-test",
"imageRef" : "%(host)s/openstack/images/%(image_id)s",
"flavorRef" : "%(host)s/openstack/flavors/1",
"metadata" : {
"My Server Name" : "Apache1"
},
"personality" : [
{
"path" : "/etc/banner.txt",
"contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
}
]
}
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="http://docs.openstack.org/compute/api/v1.1" imageRef="%(host)s/openstack/images/%(image_id)s" flavorRef="%(host)s/openstack/flavors/1" name="new-server-test">
<metadata>
<meta key="My Server Name">Apache1</meta>
</metadata>
<personality>
<file path="/etc/banner.txt">
ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp
dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k
IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs
c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g
QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo
ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv
dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy
c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6
b25zLiINCg0KLVJpY2hhcmQgQmFjaA==
</file>
</personality>
</server>

View File

@ -0,0 +1,16 @@
{
"server": {
"adminPass": "%(password)s",
"id": "%(id)s",
"links": [
{
"href": "%(host)s/v2/openstack/servers/%(uuid)s",
"rel": "self"
},
{
"href": "%(host)s/openstack/servers/%(uuid)s",
"rel": "bookmark"
}
]
}
}

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="%(id)s" adminPass="%(password)s">
<metadata/>
<atom:link href="%(host)s/v2/openstack/servers/%(uuid)s" rel="self"/>
<atom:link href="%(host)s/openstack/servers/%(uuid)s" rel="bookmark"/>
</server>

View File

@ -0,0 +1,56 @@
{
"servers": [
{
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"addr": "%(ip)s",
"version": 4
}
]
},
"created": "%(timestamp)s",
"flavor": {
"id": "1",
"links": [
{
"href": "%(host)s/openstack/flavors/1",
"rel": "bookmark"
}
]
},
"hostId": "%(hostid)s",
"id": "%(id)s",
"image": {
"id": "%(uuid)s",
"links": [
{
"href": "%(host)s/openstack/images/%(uuid)s",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "%(host)s/v2/openstack/servers/%(id)s",
"rel": "self"
},
{
"href": "%(host)s/openstack/servers/%(id)s",
"rel": "bookmark"
}
],
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"progress": 0,
"status": "ACTIVE",
"tenant_id": "openstack",
"updated": "%(timestamp)s",
"user_id": "fake"
}
]
}

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
<servers xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server status="ACTIVE" updated="%(timestamp)s" hostId="%(hostid)s" name="new-server-test" created="%(timestamp)s" userId="fake" tenantId="openstack" accessIPv4="" accessIPv6="" progress="0" id="%(id)s">
<image id="%(uuid)s">
<atom:link href="%(host)s/openstack/images/%(uuid)s" rel="bookmark"/>
</image>
<flavor id="1">
<atom:link href="%(host)s/openstack/flavors/1" rel="bookmark"/>
</flavor>
<metadata>
<meta key="My Server Name">Apache1</meta>
</metadata>
<addresses>
<network id="private">
<ip version="4" addr="%(ip)s"/>
</network>
</addresses>
<atom:link href="%(host)s/v2/openstack/servers/%(id)s" rel="self"/>
<atom:link href="%(host)s/openstack/servers/%(id)s" rel="bookmark"/>
</server>
</servers>

View File

@ -0,0 +1,18 @@
{
"servers": [
{
"id": "%(id)s",
"links": [
{
"href": "%(host)s/v2/openstack/servers/%(id)s",
"rel": "self"
},
{
"href": "%(host)s/openstack/servers/%(id)s",
"rel": "bookmark"
}
],
"name": "new-server-test"
}
]
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<servers xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server name="new-server-test" id="%(id)s">
<atom:link href="%(host)s/v2/openstack/servers/%(id)s" rel="self"/>
<atom:link href="%(host)s/openstack/servers/%(id)s" rel="bookmark"/>
</server>
</servers>

View File

@ -457,6 +457,16 @@ class ServersSampleAllExtensionXmlTest(ServersSampleXmlTest):
all_extensions = True
class ServersSampleHideAddressesJsonTest(ServersSampleJsonTest):
extension_name = '.'.join(('nova.api.openstack.compute.contrib',
'hide_server_addresses',
'Hide_server_addresses'))
class ServersSampleHideAddressesXMLTest(ServersSampleHideAddressesJsonTest):
ctype = 'xml'
class ServersMetadataJsonTest(ServersSampleBase):
def _create_and_set(self, subs):
uuid = self._post_server()