# vim: tabstop=4 shiftwidth=4 softtabstop=4 # # Copyright 2011 Cisco Systems, Inc. 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. # # @author: Sumit Naiksatam, Cisco Systems Inc. # """ Implements a UCSM XML API Client """ import httplib import logging from xml.etree import ElementTree as et from quantum.plugins.cisco.common import cisco_constants as const LOG = logging.getLogger(__name__) COOKIE_VALUE = "cookie_placeholder" PROFILE_NAME = "profilename_placeholder" PROFILE_CLIENT = "profileclient_placeholder" VLAN_NAME = "vlanname_placeholder" VLAN_ID = "vlanid_placeholder" OLD_VLAN_NAME = "old_vlanname_placeholder" BLADE_VALUE = "blade_number_placeholder" BLADE_DN_VALUE = "blade_dn_placeholder" CHASSIS_VALUE = "chassis_number_placeholder" DYNAMIC_NIC_PREFIX = "eth" # The following are standard strings, messages used to communicate with UCSM, #only place holder values change for each message HEADERS = {"Content-Type": "text/xml"} METHOD = "POST" URL = "/nuova" CREATE_VLAN = (' ' ' ' ' ') CREATE_PROFILE = (' ' ' ' ' ' ' ') ASSOCIATE_PROFILE = (' ' ' ') CHANGE_VLAN_IN_PROFILE = (' ') DELETE_VLAN = (' ' + ' ' + ' ") conn.request(METHOD, URL, login_data, HEADERS) response = conn.getresponse() response_data = response.read() # TODO (Sumit): If login is not successful, throw exception xml_tree = et.XML(response_data) cookie = xml_tree.attrib["outCookie"] data = data.replace(COOKIE_VALUE, cookie) conn.request(METHOD, URL, data, HEADERS) response = conn.getresponse() response_data = response.read() post_data_response = response_data logout_data = "" conn.request(METHOD, URL, logout_data, HEADERS) response = conn.getresponse() response_data = response.read() return post_data_response def _create_vlan_post_data(self, vlan_name, vlan_id): """Create command""" data = CREATE_VLAN.replace(VLAN_NAME, vlan_name) data = data.replace(VLAN_ID, vlan_id) return data def _create_profile_post_data(self, profile_name, vlan_name): """Create command""" data = CREATE_PROFILE.replace(PROFILE_NAME, profile_name) data = data.replace(VLAN_NAME, vlan_name) return data def _create_pclient_post_data(self, profile_name, profile_client_name): """Create command""" data = ASSOCIATE_PROFILE.replace(PROFILE_NAME, profile_name) data = data.replace(PROFILE_CLIENT, profile_client_name) return data def _change_vlaninprof_post_data(self, profile_name, old_vlan_name, new_vlan_name): """Create command""" data = CHANGE_VLAN_IN_PROFILE.replace(PROFILE_NAME, profile_name) data = data.replace(OLD_VLAN_NAME, old_vlan_name) data = data.replace(VLAN_NAME, new_vlan_name) return data def _delete_vlan_post_data(self, vlan_name): """Create command""" data = DELETE_VLAN.replace(VLAN_NAME, vlan_name) return data def _delete_profile_post_data(self, profile_name): """Create command""" data = DELETE_PROFILE.replace(PROFILE_NAME, profile_name) return data def _get_blade_interfaces_post_data(self, chassis_number, blade_number): """Create command""" data = GET_BLADE_INTERFACES.replace(CHASSIS_VALUE, chassis_number) data = data.replace(BLADE_VALUE, blade_number) return data def _get_blade_intf_st_post_data(self, blade_dn): """Create command""" data = GET_BLADE_INTERFACE_STATE.replace(BLADE_DN_VALUE, blade_dn) return data def _get_blade_interfaces(self, chassis_number, blade_number, ucsm_ip, ucsm_username, ucsm_password): """Create command""" data = self._get_blade_interfaces_post_data(chassis_number, blade_number) response = self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) elements = ( et.XML(response).find("outConfigs").findall("adaptorHostEthIf") ) blade_interfaces = {} for element in elements: dist_name = element.get("dn", default=None) if dist_name: order = element.get("order", default=None) blade_interface = { const.BLADE_INTF_DN: dist_name, const.BLADE_INTF_ORDER: order, const.BLADE_INTF_LINK_STATE: None, const.BLADE_INTF_OPER_STATE: None, const.BLADE_INTF_INST_TYPE: None, const.BLADE_INTF_RHEL_DEVICE_NAME: self._get_rhel_device_name(order), } blade_interfaces[dist_name] = blade_interface return blade_interfaces def _get_blade_interface_state(self, blade_intf, ucsm_ip, ucsm_username, ucsm_password): """Create command""" data = (self._get_blade_intf_st_post_data( blade_intf[const.BLADE_INTF_DN])) response = self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) elements = et.XML(response).find("outConfigs").findall("dcxVIf") for element in elements: blade_intf[const.BLADE_INTF_LINK_STATE] = element.get("linkState", default=None) blade_intf[const.BLADE_INTF_OPER_STATE] = element.get("operState", default=None) blade_intf[const.BLADE_INTF_INST_TYPE] = element.get("instType", default=None) def _get_rhel_device_name(self, order): """Get the device name as on the RHEL host""" device_name = const.RHEL_DEVICE_NAME_REPFIX + str(int(order) - 1) return device_name def create_vlan(self, vlan_name, vlan_id, ucsm_ip, ucsm_username, ucsm_password): """Create request for UCSM""" data = self._create_vlan_post_data(vlan_name, vlan_id) self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) def create_profile(self, profile_name, vlan_name, ucsm_ip, ucsm_username, ucsm_password): """Create request for UCSM""" data = self._create_profile_post_data(profile_name, vlan_name) self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) data = self._create_pclient_post_data(profile_name, profile_name[-16:]) self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) def change_vlan_in_profile(self, profile_name, old_vlan_name, new_vlan_name, ucsm_ip, ucsm_username, ucsm_password): """Create request for UCSM""" data = self._change_vlaninprof_post_data(profile_name, old_vlan_name, new_vlan_name) self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) def get_blade_data(self, chassis_number, blade_number, ucsm_ip, ucsm_username, ucsm_password): """ Returns only the dynamic interfaces on the blade """ blade_interfaces = self._get_blade_interfaces(chassis_number, blade_number, ucsm_ip, ucsm_username, ucsm_password) for blade_intf in blade_interfaces.keys(): self._get_blade_interface_state(blade_interfaces[blade_intf], ucsm_ip, ucsm_username, ucsm_password) if ((blade_interfaces[blade_intf][const.BLADE_INTF_INST_TYPE] != const.BLADE_INTF_DYNAMIC)): blade_interfaces.pop(blade_intf) return blade_interfaces def delete_vlan(self, vlan_name, ucsm_ip, ucsm_username, ucsm_password): """Create request for UCSM""" data = self._delete_vlan_post_data(vlan_name) self._post_data(ucsm_ip, ucsm_username, ucsm_password, data) def delete_profile(self, profile_name, ucsm_ip, ucsm_username, ucsm_password): """Create request for UCSM""" data = self._delete_profile_post_data(profile_name) self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)