See description of change... what's the difference between that message and this message again?
This commit is contained in:
@@ -24,11 +24,11 @@
|
|||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import utils
|
from nova import utils
|
||||||
from nova import wsgi
|
from nova import wsgi
|
||||||
from nova.endpoint import rackspace
|
from nova.endpoint import newapi
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_integer('cc_port', 8773, 'cloud controller port')
|
flags.DEFINE_integer('cc_port', 8773, 'cloud controller port')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
utils.default_flagfile()
|
utils.default_flagfile()
|
||||||
wsgi.run_server(rackspace.API(), FLAGS.cc_port)
|
wsgi.run_server(newapi.APIVersionRouter(), FLAGS.cc_port)
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""
|
|
||||||
:mod:`nova.endpoint` -- Main NOVA Api endpoints
|
|
||||||
=====================================================
|
|
||||||
|
|
||||||
.. automodule:: nova.endpoint
|
|
||||||
:platform: Unix
|
|
||||||
:synopsis: REST APIs for all nova functions
|
|
||||||
.. moduleauthor:: Jesse Andrews <jesse@ansolabs.com>
|
|
||||||
.. moduleauthor:: Devin Carlen <devin.carlen@gmail.com>
|
|
||||||
.. moduleauthor:: Vishvananda Ishaya <vishvananda@yahoo.com>
|
|
||||||
.. moduleauthor:: Joshua McKenty <joshua@cognition.ca>
|
|
||||||
.. moduleauthor:: Manish Singh <yosh@gimp.org>
|
|
||||||
.. moduleauthor:: Andy Smith <andy@anarkystic.com>
|
|
||||||
"""
|
|
||||||
|
|||||||
22
nova/endpoint/aws/__init__.py
Normal file
22
nova/endpoint/aws/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import routes
|
||||||
|
import webob.dec
|
||||||
|
|
||||||
|
from nova import wsgi
|
||||||
|
|
||||||
|
# TODO(gundlach): temp
|
||||||
|
class API(wsgi.Router):
|
||||||
|
"""WSGI entry point for all AWS API requests."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
mapper = routes.Mapper()
|
||||||
|
|
||||||
|
mapper.connect(None, "{all:.*}", controller=self.dummy)
|
||||||
|
|
||||||
|
super(API, self).__init__(mapper)
|
||||||
|
|
||||||
|
@webob.dec.wsgify
|
||||||
|
def dummy(self, req):
|
||||||
|
#TODO(gundlach)
|
||||||
|
msg = "dummy response -- please hook up __init__() to cloud.py instead"
|
||||||
|
return repr({ 'dummy': msg,
|
||||||
|
'kwargs': repr(req.environ['wsgiorg.routing_args'][1]) })
|
||||||
51
nova/endpoint/newapi.py
Normal file
51
nova/endpoint/newapi.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2010 United States Government as represented by the
|
||||||
|
# Administrator of the National Aeronautics and Space Administration.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
:mod:`nova.endpoint` -- Main NOVA Api endpoints
|
||||||
|
=====================================================
|
||||||
|
|
||||||
|
.. automodule:: nova.endpoint
|
||||||
|
:platform: Unix
|
||||||
|
:synopsis: REST APIs for all nova functions
|
||||||
|
.. moduleauthor:: Jesse Andrews <jesse@ansolabs.com>
|
||||||
|
.. moduleauthor:: Devin Carlen <devin.carlen@gmail.com>
|
||||||
|
.. moduleauthor:: Vishvananda Ishaya <vishvananda@yahoo.com>
|
||||||
|
.. moduleauthor:: Joshua McKenty <joshua@cognition.ca>
|
||||||
|
.. moduleauthor:: Manish Singh <yosh@gimp.org>
|
||||||
|
.. moduleauthor:: Andy Smith <andy@anarkystic.com>
|
||||||
|
"""
|
||||||
|
|
||||||
|
from nova import wsgi
|
||||||
|
import routes
|
||||||
|
from nova.endpoint import rackspace
|
||||||
|
from nova.endpoint import aws
|
||||||
|
|
||||||
|
class APIVersionRouter(wsgi.Router):
|
||||||
|
"""Routes top-level requests to the appropriate API."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
mapper = routes.Mapper()
|
||||||
|
|
||||||
|
rsapi = rackspace.API()
|
||||||
|
mapper.connect(None, "/v1.0/{path_info:.*}", controller=rsapi)
|
||||||
|
|
||||||
|
mapper.connect(None, "/ec2/{path_info:.*}", controller=aws.API())
|
||||||
|
|
||||||
|
super(APIVersionRouter, self).__init__(mapper)
|
||||||
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""
|
|
||||||
Rackspace API Endpoint
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
|
|
||||||
import webob.dec
|
|
||||||
import webob.exc
|
|
||||||
|
|
||||||
from nova import flags
|
|
||||||
from nova import rpc
|
|
||||||
from nova import utils
|
|
||||||
from nova import wsgi
|
|
||||||
from nova.auth import manager
|
|
||||||
from nova.compute import model as compute
|
|
||||||
from nova.network import model as network
|
|
||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
|
||||||
flags.DEFINE_string('cloud_topic', 'cloud', 'the topic clouds listen on')
|
|
||||||
|
|
||||||
|
|
||||||
class API(wsgi.Middleware):
|
|
||||||
"""Entry point for all requests."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(API, self).__init__(Router(webob.exc.HTTPNotFound()))
|
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
|
||||||
context = {}
|
|
||||||
if "HTTP_X_AUTH_TOKEN" in environ:
|
|
||||||
context['user'] = manager.AuthManager().get_user_from_access_key(
|
|
||||||
environ['HTTP_X_AUTH_TOKEN'])
|
|
||||||
if context['user']:
|
|
||||||
context['project'] = manager.AuthManager().get_project(
|
|
||||||
context['user'].name)
|
|
||||||
if "user" not in context:
|
|
||||||
return webob.exc.HTTPForbidden()(environ, start_response)
|
|
||||||
environ['nova.context'] = context
|
|
||||||
return self.application(environ, start_response)
|
|
||||||
|
|
||||||
|
|
||||||
class Router(wsgi.Router):
|
|
||||||
"""Route requests to the next WSGI application."""
|
|
||||||
|
|
||||||
def _build_map(self):
|
|
||||||
"""Build routing map for authentication and cloud."""
|
|
||||||
self._connect("/v1.0", controller=AuthenticationAPI())
|
|
||||||
cloud = CloudServerAPI()
|
|
||||||
self._connect("/servers", controller=cloud.launch_server,
|
|
||||||
conditions={"method": ["POST"]})
|
|
||||||
self._connect("/servers/{server_id}", controller=cloud.delete_server,
|
|
||||||
conditions={'method': ["DELETE"]})
|
|
||||||
self._connect("/servers", controller=cloud)
|
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationAPI(wsgi.Application):
|
|
||||||
"""Handle all authorization requests through WSGI applications."""
|
|
||||||
|
|
||||||
@webob.dec.wsgify
|
|
||||||
def __call__(self, req): # pylint: disable-msg=W0221
|
|
||||||
# TODO(todd): make a actual session with a unique token
|
|
||||||
# just pass the auth key back through for now
|
|
||||||
res = webob.Response()
|
|
||||||
res.status = '204 No Content'
|
|
||||||
res.headers.add('X-Server-Management-Url', req.host_url)
|
|
||||||
res.headers.add('X-Storage-Url', req.host_url)
|
|
||||||
res.headers.add('X-CDN-Managment-Url', req.host_url)
|
|
||||||
res.headers.add('X-Auth-Token', req.headers['X-Auth-Key'])
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
class CloudServerAPI(wsgi.Application):
|
|
||||||
"""Handle all server requests through WSGI applications."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(CloudServerAPI, self).__init__()
|
|
||||||
self.instdir = compute.InstanceDirectory()
|
|
||||||
self.network = network.PublicNetworkController()
|
|
||||||
|
|
||||||
@webob.dec.wsgify
|
|
||||||
def __call__(self, req): # pylint: disable-msg=W0221
|
|
||||||
value = {"servers": []}
|
|
||||||
for inst in self.instdir.all:
|
|
||||||
value["servers"].append(self.instance_details(inst))
|
|
||||||
return json.dumps(value)
|
|
||||||
|
|
||||||
def instance_details(self, inst): # pylint: disable-msg=R0201
|
|
||||||
"""Build the data structure to represent details for an instance."""
|
|
||||||
return {
|
|
||||||
"id": inst.get("instance_id", None),
|
|
||||||
"imageId": inst.get("image_id", None),
|
|
||||||
"flavorId": inst.get("instacne_type", None),
|
|
||||||
"hostId": inst.get("node_name", None),
|
|
||||||
"status": inst.get("state", "pending"),
|
|
||||||
"addresses": {
|
|
||||||
"public": [network.get_public_ip_for_instance(
|
|
||||||
inst.get("instance_id", None))],
|
|
||||||
"private": [inst.get("private_dns_name", None)]},
|
|
||||||
|
|
||||||
# implemented only by Rackspace, not AWS
|
|
||||||
"name": inst.get("name", "Not-Specified"),
|
|
||||||
|
|
||||||
# not supported
|
|
||||||
"progress": "Not-Supported",
|
|
||||||
"metadata": {
|
|
||||||
"Server Label": "Not-Supported",
|
|
||||||
"Image Version": "Not-Supported"}}
|
|
||||||
|
|
||||||
@webob.dec.wsgify
|
|
||||||
def launch_server(self, req):
|
|
||||||
"""Launch a new instance."""
|
|
||||||
data = json.loads(req.body)
|
|
||||||
inst = self.build_server_instance(data, req.environ['nova.context'])
|
|
||||||
rpc.cast(
|
|
||||||
FLAGS.compute_topic, {
|
|
||||||
"method": "run_instance",
|
|
||||||
"args": {"instance_id": inst.instance_id}})
|
|
||||||
|
|
||||||
return json.dumps({"server": self.instance_details(inst)})
|
|
||||||
|
|
||||||
def build_server_instance(self, env, context):
|
|
||||||
"""Build instance data structure and save it to the data store."""
|
|
||||||
reservation = utils.generate_uid('r')
|
|
||||||
ltime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
|
|
||||||
inst = self.instdir.new()
|
|
||||||
inst['name'] = env['server']['name']
|
|
||||||
inst['image_id'] = env['server']['imageId']
|
|
||||||
inst['instance_type'] = env['server']['flavorId']
|
|
||||||
inst['user_id'] = context['user'].id
|
|
||||||
inst['project_id'] = context['project'].id
|
|
||||||
inst['reservation_id'] = reservation
|
|
||||||
inst['launch_time'] = ltime
|
|
||||||
inst['mac_address'] = utils.generate_mac()
|
|
||||||
address = self.network.allocate_ip(
|
|
||||||
inst['user_id'],
|
|
||||||
inst['project_id'],
|
|
||||||
mac=inst['mac_address'])
|
|
||||||
inst['private_dns_name'] = str(address)
|
|
||||||
inst['bridge_name'] = network.BridgedNetwork.get_network_for_project(
|
|
||||||
inst['user_id'],
|
|
||||||
inst['project_id'],
|
|
||||||
'default')['bridge_name']
|
|
||||||
# key_data, key_name, ami_launch_index
|
|
||||||
# TODO(todd): key data or root password
|
|
||||||
inst.save()
|
|
||||||
return inst
|
|
||||||
|
|
||||||
@webob.dec.wsgify
|
|
||||||
@wsgi.route_args
|
|
||||||
def delete_server(self, req, route_args): # pylint: disable-msg=R0201
|
|
||||||
"""Delete an instance."""
|
|
||||||
owner_hostname = None
|
|
||||||
instance = compute.Instance.lookup(route_args['server_id'])
|
|
||||||
if instance:
|
|
||||||
owner_hostname = instance["node_name"]
|
|
||||||
if not owner_hostname:
|
|
||||||
return webob.exc.HTTPNotFound("Did not find image, or it was "
|
|
||||||
"not in a running state.")
|
|
||||||
rpc_transport = "%s:%s" % (FLAGS.compute_topic, owner_hostname)
|
|
||||||
rpc.cast(rpc_transport,
|
|
||||||
{"method": "reboot_instance",
|
|
||||||
"args": {"instance_id": route_args['server_id']}})
|
|
||||||
req.status = "202 Accepted"
|
|
||||||
83
nova/endpoint/rackspace/__init__.py
Normal file
83
nova/endpoint/rackspace/__init__.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2010 United States Government as represented by the
|
||||||
|
# Administrator of the National Aeronautics and Space Administration.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Rackspace API Endpoint
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
import webob.dec
|
||||||
|
import webob.exc
|
||||||
|
import routes
|
||||||
|
|
||||||
|
from nova import flags
|
||||||
|
from nova import wsgi
|
||||||
|
from nova.auth import manager
|
||||||
|
from nova.endpoint.rackspace import controllers
|
||||||
|
|
||||||
|
|
||||||
|
class API(wsgi.Middleware):
|
||||||
|
"""WSGI entry point for all Rackspace API requests."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
app = AuthMiddleware(APIRouter())
|
||||||
|
super(API, self).__init__(app)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthMiddleware(wsgi.Middleware):
|
||||||
|
"""Authorize the rackspace API request or return an HTTP Forbidden."""
|
||||||
|
|
||||||
|
#TODO(gundlach): isn't this the old Nova API's auth? Should it be replaced
|
||||||
|
#with correct RS API auth?
|
||||||
|
|
||||||
|
@webob.dec.wsgify
|
||||||
|
def __call__(self, req):
|
||||||
|
context = {}
|
||||||
|
if "HTTP_X_AUTH_TOKEN" in req.environ:
|
||||||
|
context['user'] = manager.AuthManager().get_user_from_access_key(
|
||||||
|
req.environ['HTTP_X_AUTH_TOKEN'])
|
||||||
|
if context['user']:
|
||||||
|
context['project'] = manager.AuthManager().get_project(
|
||||||
|
context['user'].name)
|
||||||
|
if "user" not in context:
|
||||||
|
return webob.exc.HTTPForbidden()
|
||||||
|
req.environ['nova.context'] = context
|
||||||
|
return self.application
|
||||||
|
|
||||||
|
|
||||||
|
class APIRouter(wsgi.Router):
|
||||||
|
"""
|
||||||
|
Routes requests on the Rackspace API to the appropriate controller
|
||||||
|
and method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
mapper = routes.Mapper()
|
||||||
|
|
||||||
|
mapper.resource("server", "servers",
|
||||||
|
controller=controllers.ServersController())
|
||||||
|
mapper.resource("image", "images",
|
||||||
|
controller=controllers.ImagesController())
|
||||||
|
mapper.resource("flavor", "flavors",
|
||||||
|
controller=controllers.FlavorsController())
|
||||||
|
mapper.resource("sharedipgroup", "sharedipgroups",
|
||||||
|
controller=controllers.SharedIpGroupsController())
|
||||||
|
|
||||||
|
super(APIRouter, self).__init__(mapper)
|
||||||
5
nova/endpoint/rackspace/controllers/__init__.py
Normal file
5
nova/endpoint/rackspace/controllers/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from nova.endpoint.rackspace.controllers.images import ImagesController
|
||||||
|
from nova.endpoint.rackspace.controllers.flavors import FlavorsController
|
||||||
|
from nova.endpoint.rackspace.controllers.servers import ServersController
|
||||||
|
from nova.endpoint.rackspace.controllers.sharedipgroups import \
|
||||||
|
SharedIpGroupsController
|
||||||
9
nova/endpoint/rackspace/controllers/base.py
Normal file
9
nova/endpoint/rackspace/controllers/base.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from nova import wsgi
|
||||||
|
|
||||||
|
class BaseController(wsgi.Controller):
|
||||||
|
@classmethod
|
||||||
|
def render(cls, instance):
|
||||||
|
if isinstance(instance, list):
|
||||||
|
return { cls.entity_name : cls.render(instance) }
|
||||||
|
else:
|
||||||
|
return { "TODO": "TODO" }
|
||||||
1
nova/endpoint/rackspace/controllers/flavors.py
Normal file
1
nova/endpoint/rackspace/controllers/flavors.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
class FlavorsController(object): pass
|
||||||
1
nova/endpoint/rackspace/controllers/images.py
Normal file
1
nova/endpoint/rackspace/controllers/images.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
class ImagesController(object): pass
|
||||||
63
nova/endpoint/rackspace/controllers/servers.py
Normal file
63
nova/endpoint/rackspace/controllers/servers.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
from nova import rpc
|
||||||
|
from nova.compute import model as compute
|
||||||
|
from nova.endpoint.rackspace.controllers.base import BaseController
|
||||||
|
|
||||||
|
class ServersController(BaseController):
|
||||||
|
entity_name = 'servers'
|
||||||
|
|
||||||
|
def index(self, **kwargs):
|
||||||
|
return [instance_details(inst) for inst in compute.InstanceDirectory().all]
|
||||||
|
|
||||||
|
def show(self, **kwargs):
|
||||||
|
instance_id = kwargs['id']
|
||||||
|
return compute.InstanceDirectory().get(instance_id)
|
||||||
|
|
||||||
|
def delete(self, **kwargs):
|
||||||
|
instance_id = kwargs['id']
|
||||||
|
instance = compute.InstanceDirectory().get(instance_id)
|
||||||
|
if not instance:
|
||||||
|
raise ServerNotFound("The requested server was not found")
|
||||||
|
instance.destroy()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create(self, **kwargs):
|
||||||
|
inst = self.build_server_instance(kwargs['server'])
|
||||||
|
rpc.cast(
|
||||||
|
FLAGS.compute_topic, {
|
||||||
|
"method": "run_instance",
|
||||||
|
"args": {"instance_id": inst.instance_id}})
|
||||||
|
|
||||||
|
def update(self, **kwargs):
|
||||||
|
instance_id = kwargs['id']
|
||||||
|
instance = compute.InstanceDirectory().get(instance_id)
|
||||||
|
if not instance:
|
||||||
|
raise ServerNotFound("The requested server was not found")
|
||||||
|
instance.update(kwargs['server'])
|
||||||
|
instance.save()
|
||||||
|
|
||||||
|
def build_server_instance(self, env):
|
||||||
|
"""Build instance data structure and save it to the data store."""
|
||||||
|
reservation = utils.generate_uid('r')
|
||||||
|
ltime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
|
||||||
|
inst = self.instdir.new()
|
||||||
|
inst['name'] = env['server']['name']
|
||||||
|
inst['image_id'] = env['server']['imageId']
|
||||||
|
inst['instance_type'] = env['server']['flavorId']
|
||||||
|
inst['user_id'] = env['user']['id']
|
||||||
|
inst['project_id'] = env['project']['id']
|
||||||
|
inst['reservation_id'] = reservation
|
||||||
|
inst['launch_time'] = ltime
|
||||||
|
inst['mac_address'] = utils.generate_mac()
|
||||||
|
address = self.network.allocate_ip(
|
||||||
|
inst['user_id'],
|
||||||
|
inst['project_id'],
|
||||||
|
mac=inst['mac_address'])
|
||||||
|
inst['private_dns_name'] = str(address)
|
||||||
|
inst['bridge_name'] = network.BridgedNetwork.get_network_for_project(
|
||||||
|
inst['user_id'],
|
||||||
|
inst['project_id'],
|
||||||
|
'default')['bridge_name']
|
||||||
|
# key_data, key_name, ami_launch_index
|
||||||
|
# TODO(todd): key data or root password
|
||||||
|
inst.save()
|
||||||
|
return inst
|
||||||
1
nova/endpoint/rackspace/controllers/sharedipgroups.py
Normal file
1
nova/endpoint/rackspace/controllers/sharedipgroups.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
class SharedIpGroupsController(object): pass
|
||||||
Reference in New Issue
Block a user