nova/nova/console/vmrc_manager.py

145 lines
5.9 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 Citrix Systems, Inc.
# Copyright 2011 OpenStack Foundation
#
# 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.
"""VMRC Console Manager."""
from oslo.config import cfg
from nova.compute import rpcapi as compute_rpcapi
from nova import exception
from nova import manager
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.virt.vmwareapi import driver as vmwareapi_conn
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.import_opt('console_driver', 'nova.console.manager')
CONF.import_opt('console_public_hostname', 'nova.console.manager')
class ConsoleVMRCManager(manager.Manager):
"""Manager to handle VMRC connections for accessing instance consoles."""
def __init__(self, console_driver=None, *args, **kwargs):
self.driver = importutils.import_object(CONF.console_driver)
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
super(ConsoleVMRCManager, self).__init__(*args, **kwargs)
def init_host(self):
self.sessions = {}
self.driver.init_host()
def _get_vim_session(self, pool):
"""Get VIM session for the pool specified."""
vim_session = None
if pool['id'] not in self.sessions.keys():
vim_session = vmwareapi_conn.VMwareAPISession(
pool['address'],
pool['username'],
pool['password'],
CONF.console_vmrc_error_retries)
self.sessions[pool['id']] = vim_session
return self.sessions[pool['id']]
def _generate_console(self, context, pool, name, instance_id, instance):
"""Sets up console for the instance."""
LOG.debug(_('Adding console'))
password = self.driver.generate_password(
self._get_vim_session(pool),
pool,
instance.name)
console_data = {'instance_name': name,
'instance_id': instance_id,
'password': password,
'pool_id': pool['id']}
console_data['port'] = self.driver.get_port(context)
console = self.db.console_create(context, console_data)
self.driver.setup_console(context, console)
return console
def add_console(self, context, instance_id, password=None,
port=None, **kwargs):
"""Adds a console for the instance.
If it is one time password, then we generate new console credentials.
"""
instance = self.db.instance_get(context, instance_id)
host = instance['host']
name = instance['name']
pool = self.get_pool_for_instance_host(context, host)
try:
console = self.db.console_get_by_pool_instance(context,
pool['id'],
instance['uuid'])
if self.driver.is_otp():
console = self._generate_console(context,
pool,
name,
instance_id,
instance)
except exception.NotFound:
console = self._generate_console(context,
pool,
name,
instance_id,
instance)
return console['id']
def remove_console(self, context, console_id, **_kwargs):
"""Removes a console entry."""
try:
console = self.db.console_get(context, console_id)
except exception.NotFound:
LOG.debug(_('Tried to remove non-existent console '
'%(console_id)s.') % {'console_id': console_id})
return
LOG.debug(_('Removing console '
'%(console_id)s.') % {'console_id': console_id})
self.db.console_delete(context, console_id)
self.driver.teardown_console(context, console)
def get_pool_for_instance_host(self, context, instance_host):
"""Gets console pool info for the instance."""
context = context.elevated()
console_type = self.driver.console_type
try:
pool = self.db.console_pool_get_by_host_type(context,
instance_host,
self.host,
console_type)
except exception.NotFound:
pool_info = self.compute_rpcapi.get_console_pool_info(context,
console_type, instance_host)
pool_info['password'] = self.driver.fix_pool_password(
pool_info['password'])
pool_info['host'] = self.host
# ESX Address or Proxy Address
public_host_name = pool_info['address']
if CONF.console_public_hostname:
public_host_name = CONF.console_public_hostname
pool_info['public_hostname'] = public_host_name
pool_info['console_type'] = console_type
pool_info['compute_host'] = instance_host
pool = self.db.console_pool_create(context, pool_info)
return pool