# Copyright 2013 Cisco Systems, Inc.
#
# 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.
"""
This module contains the APIs used to launch ucs kvm.
"""
try:
from urllib import urlencode
except:
from urllib.parse import urlencode
import subprocess
import logging
from .. import ucsgenutils
from ..ucsconstants import NamingId, YesOrNo
from ..ucsexception import UcsWarning, UcsValidationException, UcsException
from ..ucscoremeta import UcsVersion
log = logging.getLogger('ucs')
class _ParamKvm(object):
# Internal class to act as enum to support ucs_kvm_launch utility.
CENTRALE_PASSWORD = "centralePassword"
CENTRALE_USER = "centraleUser"
DN = "dn"
FRAME_TITLE = "frame_title"
KVM_IP_ADDR = "kvmIpAddr"
KVM_PASSWORD = "kvmPassword"
KVM_PN_DN = "kvmPnDn"
KVM_USER = "kvmUser"
TEMP_UNPW = "tempunpw"
KVM_DN = "kvmDn"
[docs]def ucs_kvm_launch(handle, service_profile=None, blade=None, rack_unit=None,
frame_title=None, need_url=False):
"""
ucs_kvm_launch launches the kvm session for a specified server.
Args:
handle (UcsHandle)
service_profile (LsServer)
blade (ComputeBlade)
rack_unit (ComputeRackUnit)
frame_title (str): title of launched frame
need_url (bool): True/False,
Returns URL to launch kvm, if True
Example:
# sp is service profile object \n
ucs_kvm_launch(handle, service_profile=sp)\n
ucs_kvm_launch(handle, service_profile=sp, frame_title="using sp")\n
ucs_kvm_launch(handle, service_profile=sp, need_url=True)\n
# blade1 is ComputeBlade object\n
ucs_kvm_launch(handle, blade=blade1)\n
# rack1 is ComputeRackUnit object\n
ucs_kvm_launch(handle, rack_unit=rack1)\n
"""
from ..mometa.mgmt.MgmtIf import MgmtIfConsts
from ..ucsmethodfactory import config_scope
from ..ucsmethodfactory import aaa_get_n_compute_auth_token_by_dn
if (blade is not None and rack_unit is not None) or \
(service_profile is not None and rack_unit is not None) or \
(blade is not None and service_profile is not None):
raise UcsValidationException(
"Provide only one parameter from blade, "
"rack_unit and service profile.")
if service_profile is None and blade is None and rack_unit is None:
raise UcsValidationException(
"Provide at least one parameter from blade, rack_unit and "
"service profile.")
min_version = UcsVersion('1.4(1a)')
if handle.version < min_version:
raise UcsValidationException(
"start_kvm_session not supported for Ucs version older than %s. "
"You are connected to Ucs Version %s" % (min_version,
handle.version))
# lock = Lock()
sp_bool = False
nvc = {}
dn = None
pn_dn = None
ip_address = None
if blade is not None or rack_unit is not None:
if blade is not None:
pn_dn = blade.dn
else:
pn_dn = rack_unit.dn
nvc[_ParamKvm.DN] = pn_dn
if frame_title is None:
frame_title = handle.name + ':' + pn_dn + ' KVM Console'
nvc[_ParamKvm.FRAME_TITLE] = frame_title
nvc[_ParamKvm.KVM_PN_DN] = pn_dn
elem = config_scope(cookie=handle.cookie,
dn=pn_dn,
in_class=NamingId.MGMT_IF,
in_filter=None,
in_recursive=YesOrNo.FALSE,
in_hierarchical=YesOrNo.FALSE)
response = handle.post_elem(elem)
if response.error_code == 0:
for mgmt_if in response.out_configs.child:
if mgmt_if.subject == MgmtIfConsts.SUBJECT_BLADE and \
mgmt_if.admin_state == MgmtIfConsts.ADMIN_STATE_ENABLE:
ip_address = mgmt_if.ext_ip
else:
raise UcsException(response.error_code, response.error_descr)
# If the blade does not have an IP,
# check if a service profile is associated
if ip_address is None or ip_address == '0.0.0.0':
mo = handle.query_dn(dn=pn_dn)
dn = mo.assigned_to_dn
if dn is not None:
sp_bool = True
if sp_bool or service_profile is not None:
if dn is None:
dn = service_profile.dn
if frame_title is None:
frame_title = handle.name + ':' + dn + ' KVM Console'
nvc[_ParamKvm.FRAME_TITLE] = frame_title
sp_mo = service_profile
else:
sp_mo = handle.query_dn(dn)
nvc[_ParamKvm.KVM_DN] = dn
# sp_mo = service_profile
if not sp_mo.pn_dn:
raise UcsValidationException(
'Service Profile is not associated with blade or rack_unit.')
pn_dn = sp_mo.pn_dn
nvc[_ParamKvm.DN] = pn_dn
mo_list = handle.query_children(in_dn=dn, class_id='vnicIpV4Addr')
# TODO:replace class_id with proper constantafter generating mos.py
# or Constant.py
for mo in mo_list:
# gmo = _GenericMo(mo=mo, option=WriteXmlOption.ALL)
# if 'Addr' not in gmo.properties:
# continue
# ip_address = gmo.GetAttribute('Addr')
# if ip_address is not None:
# break
if hasattr(mo, "addr") or hasattr(mo, "Addr"):
if hasattr(mo, "addr"):
ip_address = getattr(mo, "addr")
elif hasattr(mo, "Addr"):
ip_address = getattr(mo, "Addr")
if ip_address is not None:
break
if (ip_address is None or ip_address == '0.0.0.0') and \
service_profile is not None:
elem = config_scope(cookie=handle.cookie,
dn=pn_dn,
in_class=NamingId.MGMT_IF,
in_filter=None,
in_recursive=YesOrNo.FALSE,
in_hierarchical=YesOrNo.FALSE)
response = handle.post_elem(elem)
if response.error_code == 0:
for mgmt_if in response.out_configs.child:
if mgmt_if.subject == MgmtIfConsts.SUBJECT_BLADE and \
mgmt_if.admin_state == MgmtIfConsts.ADMIN_STATE_ENABLE:
ip_address = mgmt_if.ext_ip
if ip_address is None or ip_address == '0.0.0.0':
raise UcsValidationException("No assigned IP address to use.")
nvc[_ParamKvm.KVM_IP_ADDR] = ip_address
elem = aaa_get_n_compute_auth_token_by_dn(cookie=handle.cookie,
in_cookie=handle.cookie,
in_dn=pn_dn,
in_number_of=2)
response = handle.post_elem(elem)
if response.error_code == 0:
nvc[_ParamKvm.CENTRALE_PASSWORD] = response.out_tokens.split(',')[0]
nvc[_ParamKvm.CENTRALE_USER] = response.out_user
nvc[_ParamKvm.KVM_PASSWORD] = response.out_tokens.split(',')[1]
nvc[_ParamKvm.KVM_USER] = response.out_user
else:
raise UcsException(response.error_code, response.error_descr)
nvc[_ParamKvm.TEMP_UNPW] = "true"
uri = handle.uri
kvm_url = '%s/ucsm/kvm.jnlp?%s' % (uri, urlencode(nvc))
if need_url:
return kvm_url
else:
install_path = ucsgenutils.get_java_installation_path()
if install_path is not None:
subprocess.call([install_path, kvm_url])
else:
UcsWarning("Java is not installed on System.")
subprocess.Popen(kvm_url)