def set_pxe_onetime_boot_device(self, context): csapi = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, username=None, password=None, domain=CloudShellSessionContext._get_domain(context)) url = 'https://%s/redfish/v1/Systems/System.Embedded.1' % self.idrac_ip payload = {"Boot": {"BootSourceOverrideTarget": "Pxe"}} headers = {'content-type': 'application/json'} response = requests.patch(url, data=json.dumps(payload), headers=headers, verify=False, auth=(self.idrac_username, self.idrac_password)) data = response.json() statusCode = response.status_code if statusCode == 200: msg = "%s set next boot onetime boot device to: Pxe" % self.resourcename self.logger.info(msg) csapi.WriteMessageToReservationOutput( context.reservation.reservation_id, msg) csapi.SetResourceLiveStatus(self.resourcename, 'PXE Set', 'Set to PXE boot') else: detail_message = str(response.__dict__) msg = "%s set boot command failed, errror code is %s, %s" % ( self.resourcename, statusCode, detail_message) self.logger.info(msg) csapi.WriteMessageToReservationOutput( context.reservation.reservation_id, msg)
def context(session: CloudShellAPISession, test_helpers: TestHelpers, server: list) -> ResourceCommandContext: controller_address, controller_version, apikey, ports = server attributes = [ AttributeNameValue(f'{IXLOAD_CONTROLLER_MODEL}.Address', controller_address), AttributeNameValue(f'{IXLOAD_CONTROLLER_MODEL}.Controller Version', controller_version), AttributeNameValue(f'{IXLOAD_CONTROLLER_MODEL}.ApiKey', apikey), AttributeNameValue(f'{IXLOAD_CONTROLLER_MODEL}.License Server', '192.168.42.61'), AttributeNameValue(f'{IXLOAD_CONTROLLER_MODEL}.Licensing Mode', 'Perpetual') ] session.AddServiceToReservation(test_helpers.reservation_id, IXLOAD_CONTROLLER_MODEL, ALIAS, attributes) context = test_helpers.resource_command_context(service_name=ALIAS) session.AddResourcesToReservation(test_helpers.reservation_id, ports) reservation_ports = get_resources_from_reservation( context, f'{IXIA_CHASSIS_MODEL}.GenericTrafficGeneratorPort') set_family_attribute(context, reservation_ports[0].Name, 'Logical Name', 'Traffic1@Network1') set_family_attribute(context, reservation_ports[1].Name, 'Logical Name', 'Traffic2@Network2') yield context
def run_parsed_config(self, context): self._get_logger_with_reservation_id(context) session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) Reservation_Description = session.GetReservationDetails( context.reservation.reservation_id).ReservationDescription parser = parse_config.parse_commands( session, res_id=context.reservation.reservation_id, logger=self.logger) parsed_commands = parser.replace_placeholders( file_name=COREVSRXFILENAME, file_type='txt', reservation_description=Reservation_Description) # for command in parsed_commands: # self._send_command(context, command=command) result = [] try: temp_result = self._send_command(context=context, command=parsed_commands) except Exception as e: self.logger.error(e) temp_result = e result.append(temp_result) return result
def get_snmp(self, context, snmp_module_name, miboid): """ :param InitCommandContext context: this is the context passed by cloudshell automatically :param str snmp_module_name: MIB name :param str miboid: 'management information base object id' test two :return: """ session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) reservation_id = context.reservation.reservation_id logger = get_qs_logger() address = context.resource.address snmp_read_community = session.DecryptPassword( context.resource.attributes['LinuxServerShell.SNMP Read Community'] ).Value snmp_v2_parameters = SNMPV2ReadParameters( ip=address, snmp_read_community=snmp_read_community) snmp_service = QualiSnmp(snmp_v2_parameters, logger) for index, info in snmp_service.get_table(snmp_module_name, miboid).items(): session.WriteMessageToReservationOutput(reservation_id, "[{0}]".format(index)) for key, value in info.items(): session.WriteMessageToReservationOutput( reservation_id, " {0}: {1}".format(key, value)) return "\nEnd of execution"
def get_api(self): cloudshell_api_scheme = CloudShellSessionContext._get_api_scheme( self.context) if "https" in cloudshell_api_scheme.lower(): try: result = CloudShellAPISession( host=self.context.connectivity.server_address, token_id=self.context.connectivity.admin_auth_token, username=None, password=None, cloudshell_api_scheme=CloudShellSessionContext. _get_api_scheme(self.context), domain=CloudShellSessionContext._get_domain(self.context), ) except TypeError: raise Exception( self.__class__.__name__, "Current version of cloudshell api does not support https", ) else: result = CloudShellAPISession( host=self.context.connectivity.server_address, token_id=self.context.connectivity.admin_auth_token, username=None, password=None, domain=CloudShellSessionContext._get_domain(self.context), ) return result
def send_any_cmd(self, context, sendcmd): """ :param InitCommandContext context : passed in by cloudshell :param str sendcmd: the command to send to the CLI """ cli = CLI() mode = CommandMode(r'#') # for example r'%\s*$' session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) address = context.resource.address user = context.resource.attributes['LinuxServerShell.User'] password = session.DecryptPassword( context.resource.attributes['LinuxServerShell.Password']).Value session_types = [ SSHSession(host=address, username=user, password=password) ] with cli.get_session(session_types, mode) as default_session: out = default_session.send_command(sendcmd) print(out) return out
def create_session_from_config() -> CloudShellAPISession: """ Create session from data in shellfoundry config. """ config = Configuration(CloudShellConfigReader()).read() session = CloudShellAPISession(config.host, config.username, config.password, config.domain) # session.domain is Domain ID so we save the domain name in session.domain_name session.domain_name = config.domain return session
def __init__(self, printOutput=False): creds = QSCreds() appWSHPort = creds.appWSHPort appMainPort = creds.appMainPort # Start the websocket hander appWSH = tornado.web.Application([ (r"/", WebSocketHandler), ]) appWSH.listen(appWSHPort) if printOutput: csapi = CloudShellAPISession(creds.Host, creds.Un, creds.Pw, creds.Dom) csapi.WriteMessageToReservationOutput( context.reservation.reservation_id, "Head to: http://" + socket.gethostbyname(socket.gethostname()) + ":" + str(appMainPort)) # start main app settings = { "static_path": os.path.join(os.path.dirname(__file__), "static") } appMain = tornado.web.Application([ (r"/", MainHandler), ], **settings) appMain.listen(appMainPort) tornado.ioloop.IOLoop.current().start()
def _send_command(self, context, command): """ :param ResourceCommandContext context: :return: """ session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) username = context.resource.attributes.get( '{Model}.User'.format(Model=context.resource.model)) password_enc = context.resource.attributes.get( '{Model}.Password'.format(Model=context.resource.model)) password = session.DecryptPassword(password_enc).Value my_session = cloudshell_cli_handler.CreateSession( host=context.resource.address, username=username, password=password, logger=self.logger) if not isinstance(command, list): commands = [command] else: commands = command outp = my_session.send_terminal_command(commands, password=password) self.logger.info(outp) return outp
def pre_autoload_configuration_command(self, context): """ A simple example function :param cloudshell.shell.core.driver_context.ResourceCommandContext context: the context the command runs on """ self.api = CloudShellAPISession(host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain='Global') self.user_msg = get_sandbox_msg(self.api, context) self.user_msg('Checking port configuration on {0}'.format(self.name)) for attribute_name in REQUIRED_ATTRIBUTES: if attribute_name not in context.resource.attributes: raise Exception( EX_MISSING_ATTRIBUTE.format(self.model, attribute_name)) number_of_ports = int(context.resource.attributes[ATTR_NUMBER_OF_PORTS]) number_of_cpus = int(context.resource.attributes[ATTR_NUMBER_OF_CPUS]) memory_in_gbs = int(context.resource.attributes[ATTR_MEMORY_IN_GBS]) vm_changes = dict() vm_changes = self._get_nic_changes(number_of_ports, vm_changes) vm_changes = self._get_CPU_changes(number_of_cpus, vm_changes) vm_changes = self._get_memory_changes(memory_in_gbs, vm_changes) vm_changes_params = json.dumps(vm_changes) if vm_changes: self.api.ExecuteResourceConnectedCommand(context.reservation.reservation_id, context.resource.name, 'modify_vm_hardware', 'remote_app_management', [vm_changes_params]) pass
def create_session_from_deployment() -> CloudShellAPISession: """ Create session from data in deployment yaml file. """ host, username, password, domain = get_credentials_from_deployment() session = CloudShellAPISession(host, username, password, domain) # session.domain is Domain ID so we save the domain name in session.domain_name session.domain_name = domain return session
def _infoblox_connector(self, context): logger = self._get_logger(context) cs_api = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain="Global") infoblox_address = context.resource.address infoblox_username = context.resource.attributes.get( f"{context.resource.model}.User") infoblox_password = cs_api.DecryptPassword( context.resource.attributes.get( f"{context.resource.model}.Password")).Value # infoblox version as attribute infoblox_config = { "host": infoblox_address, "username": infoblox_username, "password": infoblox_password, "ssl_verify": False, "wapi_version": "2.5" } try: cs_api.WriteMessageToReservationOutput( context.reservation.reservation_id, f"Connecting to InfoBlox: '{infoblox_address}'") logger.info(f"Connecting to InfoBlox: '{infoblox_address}'") connector.LOG = logger infoblox_connector = connector.Connector(infoblox_config) return infoblox_connector except Exception as e: msg = f"Error connecting to infoblox: '{e}'" logger.error(msg) raise Exception(msg)
def delete_all_records(self, context): """ :param ResourceCommandContext context: :return: """ DNS_ATTRIBUTE = "DNS Name" logger = self._get_logger(context) logger.info("Starting delete all records") cs_api = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain="Global") reservation_details = cs_api.GetReservationDetails( context.reservation.reservation_id).ReservationDescription for resource in reservation_details.Resources: attribute_name = "{}.{}".format(resource.ResourceModelName, DNS_ATTRIBUTE) try: result = cs_api.GetAttributeValue(resource.Name, attribute_name).Value if result: try: self.delete_host_record(context, result) except Exception as e: logger.error( f"Error deleting record for '{result}'. error: {e}" ) except Exception as e: logger.info( f"Error getting DNS Attribute '{DNS_ATTRIBUTE}' on resource '{resource.Name}'. Error: {e}" )
class TestXenaChassisShell(unittest.TestCase): session = None def setUp(self): self.session = CloudShellAPISession('localhost', 'admin', 'admin', 'Global') def tearDown(self): for resource in self.session.GetResourceList('Testing').Resources: self.session.DeleteResource(resource.Name) def testHelloWorld(self): pass def test_xena_chassis(self): self._get_inventory('xena-chassis', xena_chassis['xena-chassis']) def _get_inventory(self, name, properties): attributes = [ AttributeNameValue('Xena Chassis Shell 2G.Password', properties['password']) ] resource = create_autoload_resource(self.session, 'Xena Chassis Shell 2G', properties['address'], name, attributes) self.session.AutoLoad(resource.Name) resource_details = self.session.GetResourceDetails(resource.Name) assert (len(resource_details.ChildResources) == properties['modules']) self.session.DeleteResource(resource.Name)
def get_inventory(self, context): """ Discovers the resource structure and attributes. :param AutoLoadCommandContext context: the context the command runs on :return Attribute and sub-resource information for the Shell resource :rtype: AutoLoadDetails """ session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain="Global") pw = session.DecryptPassword( context.resource.attributes['Password']).Value un = context.resource.attributes["User"] ip = context.resource.address port = str(context.resource.attributes["API Port"]) prefix = str(context.resource.attributes["API Access"]) url = prefix + "://" + ip + ":" + port + "/api" sub_resources = [] attributes = [ AutoLoadAttribute('', 'Model', 'Ixia 58xx'), AutoLoadAttribute('', 'Vendor', 'Ixia') ] # get all ports requests.packages.urllib3.disable_warnings(InsecureRequestWarning) portsRequest = requests.get(url + '/ports', auth=HTTPBasicAuth(un, pw), verify=False) portsObj = json.loads(portsRequest.text) # loop thru each port and learn more for port in portsObj: portRequest = requests.get(url + '/ports/' + str(port['id']), auth=HTTPBasicAuth(un, pw), verify=False) portObj = json.loads(portRequest.text) sub_resources.append( AutoLoadResource(model='NTO Port', name=portObj['default_name'], relative_address=str(port['id']))) attributes.append( AutoLoadAttribute(str(port['id']), 'Port Speed', portObj['media_type'])) attributes.append( AutoLoadAttribute(str(port['id']), 'Serial Number', portObj['uuid'])) attributes.append( AutoLoadAttribute( str(port['id']), 'Port Description', str(portObj['name']) + " " + str(portObj['description']))) return AutoLoadDetails(sub_resources, attributes) pass
def test_autoload_session(session: CloudShellAPISession, autoload_resource: ResourceInfo, dut: List[str]) -> None: """Test indirect (shell) auto load command.""" session.AutoLoad(autoload_resource.Name) resource_details = session.GetResourceDetails(autoload_resource.Name) assert len(resource_details.ChildResources) == 1 assert resource_details.ChildResources[0].FullAddress == f"{dut[0]}/M1"
def end_reservation(session: CloudShellAPISession, reservation_id: str) -> None: """ End and delete reservation. """ try: session.EndReservation(reservation_id) while session.GetReservationDetails(reservation_id).ReservationDescription.Status != 'Completed': time.sleep(1) session.DeleteReservation(reservation_id) except Exception as _: pass
def get_all_regular_blueprints( api: CloudShellAPISession) -> List[TopologyInfo]: all_blueprints = api.GetTopologiesByCategory().Topologies results = [] for curr_bp in all_blueprints: details = api.GetTopologyDetails(topologyFullPath=curr_bp) if details.Type == "Regular": results.append(details) return results
def run(self, resource, cmd): try: csapi = CloudShellAPISession(self._serveraddr, self._adminuser, self._adminpw, self._admindom) out = csapi.ExecuteCommand(self._resid, resource, "Resource", cmd) csapi.Logoff() self._cmdOut = out.Output return self._cmdOut except: raise CSWrapperError("Could not run command")
def get_regular_blueprints_owned_by_users( api: CloudShellAPISession, owners: List[str]) -> List[TopologyInfo]: all_blueprints = api.GetTopologiesByCategory().Topologies results = [] for curr_bp in all_blueprints: details = api.GetTopologyDetails(topologyFullPath=curr_bp) if details.Type == "Regular": for curr_owner in owners: if curr_owner == details.Owner: results.append(details) return results
def decrypt_password(self, context): """ A simple example function :param ResourceCommandContext context: the context the command runs on """ session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) password = session.DecryptPassword( context.resource.attributes['Password']).Value
def SOAP_getJobResults(self, context, sessionId, jobunitId, Id): # based on https://github.com/hinemos/hinemos/blob/cb0b0c63d16f201e62b7802a50547abd2f5b1225/HinemosClient/src_jobmanagement/com/clustercontrol/jobmanagement/util/JobEndpointWrapper.java r_id = context.reservation.reservation_id HM = data_model.Hinemos.create_from_context(context) csapisession = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) if jobunitId is None: jobunitId = "" if Id is None: Id = "" ip = context.resource.address username = HM.user password = csapisession.DecryptPassword( context.resource.attributes['Hinemos.Password']).Value with CloudShellSessionContext(context) as session: session.WriteMessageToReservationOutput( context.reservation.reservation_id, "Hinemos GetJobResults:") session.WriteMessageToReservationOutput( r_id, "-Inputs: SessionID=" + sessionId + " JobUnitId=" + jobunitId + " Id=" + Id) session.WriteMessageToReservationOutput(r_id, "-Results:") session = Session() session.auth = HTTPBasicAuth(username, password) client = Client("http://" + ip + ":8080/HinemosWS/JobEndpoint?wsdl", transport=Transport(session=session)) JobTreeItem = client.service.getJobDetailList(sessionId) for job in JobTreeItem.children: if jobunitId == "": for job_cmd in job.children: jobunitId = job.data.jobunitId self.printjobresults(context, job, jobunitId, job_cmd.data.id) else: if str(job.data.jobunitId) == jobunitId: if Id == "": for job_cmd in job.children: self.printjobresults(context, job, jobunitId, job_cmd.data.id) else: for job_cmd in job.children: if str(job_cmd.data.id) == Id: self.printjobresults(context, job, jobunitId, Id) pass
def create_reservation(session: CloudShellAPISession, reservation_name: str, topology_name: Optional[str] = None, global_inputs: Optional[List[UpdateTopologyGlobalInputsRequest]] = None): """ Create empty or topology from reservation based on input. """ if not global_inputs: global_inputs = [] end_named_reservations(session, reservation_name) if topology_name: reservation = session.CreateImmediateTopologyReservation(reservation_name, session.username, topologyFullPath=topology_name, globalInputs=global_inputs, durationInMinutes=60) else: reservation = session.CreateImmediateReservation(reservation_name, session.username, durationInMinutes=60) return reservation
def _cs_session_handler(self, context): self.address = context.resource.address self.user = context.resource.attributes['User'] self.password_hash = context.resource.attributes['Password'] domain = None try: domain = context.reservation.domain except AttributeError: domain = 'Global' self.cs_session = CloudShellAPISession(host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=domain)
def reset(self, context, cancellation_context): """ Resets the device to factory settings :param ResourceCommandContext context: The context object for the command with resource and reservation info :param CancellationContext cancellation_context: Object to signal a request for cancellation. Must be enabled in drivermetadata.xml as well """ api = CloudShellAPISession( context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, port=context.connectivity.cloudshell_api_port, domain=context.reservation.domain) api.SetResourceLiveStatus(context.resource.fullname, 'Progress 10', 'Resetting switch') ssh, channel, _ = self._connect(context) self._ssh_command(context, ssh, channel, 'configure terminal', '[^[#]# ') self._ssh_command(context, ssh, channel, 'reset factory only-traffic', ': ') self._ssh_command(context, ssh, channel, 'YES', '.') try: self._disconnect(context, ssh, channel) except: pass self._log(context, 'Waiting 30 seconds...') time.sleep(30) retries = 0 while retries < 30: try: self._log(context, 'Trying to connect...') ssh, channel, _ = self._connect(context) self._log(context, 'Reconnected to device') self._disconnect(context, ssh, channel) api.SetResourceLiveStatus( context.resource.fullname, 'Online', 'Switch finished resetting at %s ' % time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())) return except Exception as e: self._log(context, 'Not ready: ' + str(e)) self._log(context, 'Waiting 10 seconds...') time.sleep(10) retries += 1 api.SetResourceLiveStatus( context.resource.fullname, 'Error', 'Switch did not come up within 5 minutes after reset') raise Exception('Device did not come up within 5 minutes after reset')
def get_inventory(self, context): """ Will locate vm in vcenter and fill its uuid :type context: cloudshell.shell.core.context.ResourceCommandContext """ logger = get_logger_with_thread_id(context) logger.info("Start Autoload process") vcenter_vm_name = context.resource.attributes["{}.vCenter VM".format(self.SHELL_NAME)] vcenter_vm_name = vcenter_vm_name.replace("\\", "/") vcenter_name = context.resource.attributes["{}.vCenter Name".format(self.SHELL_NAME)] logger.info("Start AutoLoading VM_path: {0} on vcenter: {1}".format(vcenter_vm_name, vcenter_name)) # session = self.cs_helper.get_session(context.connectivity.server_address, # context.connectivity.admin_auth_token, # self.DOMAIN) session = CloudShellAPISession(host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=self.DOMAIN) vcenter_api_res = session.GetResourceDetails(vcenter_name) vcenter_resource = self.model_parser.convert_to_vcenter_model(vcenter_api_res) si = None try: logger.info("Connecting to vcenter ({0})".format(vcenter_api_res.Address)) si = self._get_connection_to_vcenter(self.pv_service, session, vcenter_resource, vcenter_api_res.Address) logger.info("Loading VM UUID") vm_loader = VMLoader(self.pv_service) uuid = vm_loader.load_vm_uuid_by_name(si, vcenter_resource, vcenter_vm_name) logger.info("VM UUID: {0}".format(uuid)) logger.info("Loading the IP of the VM") ip = self._try_get_ip(self.pv_service, si, uuid, vcenter_resource, logger) if ip: session.UpdateResourceAddress(context.resource.name, ip) autoload_atts = [AutoLoadAttribute("", "VmDetails", self._get_vm_details(uuid, vcenter_name))] return AutoLoadDetails([], autoload_atts) except Exception: logger.exception("Get inventory command failed") raise finally: if si: self.pv_service.disconnect(si)
def change_live_status(self, context): timestamp = datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S') session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) session.WriteMessageToReservationOutput( context.reservation.reservation_id, '{} : lock exists'.format(timestamp)) session.SetReservationLiveStatus( reservationId=context.reservation.reservation_id, liveStatusName='Private')
def health_check(self, context, cancellation_context): """ Checks if the device is up and connectable :return: Health check on resource ___ passed|failed :exception Exception: Raises an error if cannot connect """ api = CloudShellAPISession( context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, port=context.connectivity.cloudshell_api_port, domain=context.reservation.domain) rv = 'Health check on resource %s passed' % context.resource.fullname api.SetResourceLiveStatus(context.resource.fullname, 'Online', rv) return rv
def SOAP_runJob(self, context, jobunitId, jobId, jobWM=1, jobWT=1): HM = data_model.Hinemos.create_from_context(context) csapisession = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=context.reservation.domain) ip = context.resource.address username = HM.user password = csapisession.DecryptPassword( context.resource.attributes['Hinemos.Password']).Value #with CloudShellSessionContext(context) as session: #session.WriteMessageToReservationOutput(context.reservation.reservation_id, 'Password found : {}'.format(password)) session = Session() session.auth = HTTPBasicAuth(username, password) client = Client("http://" + ip + ":8080/HinemosWS/JobEndpoint?wsdl", transport=Transport(session=session)) factory = client.type_factory( 'http://jobmanagement.ws.clustercontrol.com') out = factory.outputBasicInfo() trig = factory.jobTriggerInfo() trig.trigger_type = 2 trig.trigger_info = username out.priority = 0 trig.jobCommand = "" trig.jobWaitMinute = jobWM trig.jobWaitTime = jobWT session_id = client.service.runJob(jobunitId, jobId, out, trig) with CloudShellSessionContext(context) as session: session.WriteMessageToReservationOutput( context.reservation.reservation_id, "Hinemos Runjob:") session.WriteMessageToReservationOutput( context.reservation.reservation_id, "-Inputs: JobUnitId=" + jobunitId + " JobId=" + jobId) session.WriteMessageToReservationOutput( context.reservation.reservation_id, '-RunJob Output (Session ID) = {}'.format(session_id)) pass
def connect(): """ Create Xena manager object and connect to chassis. """ global xm global chassis global port1 global port2 global session global sandbox_id session = CloudShellAPISession('localhost', 'admin', 'admin', 'Global') if 'SANDBOX_ID' in environ: sandbox_id = environ['SANDBOX_ID'] else: context = create_command_context(session, ['xena 2g/Module6/Port0', 'xena 2g/Module6/Port1'], 'Xena Controller', {}) sandbox_id = context.reservation.reservation_id reserved_port1, reserved_port2 = get_reservation_resources(session, sandbox_id, 'Xena Chassis Shell 2G.GenericTrafficGeneratorPort') port1 = get_address(reserved_port1) port2 = get_address(reserved_port2) chassis = port1.split('/')[0] logger = logging.getLogger('log') logger.setLevel('INFO') logger.addHandler(logging.StreamHandler(sys.stdout)) xm = init_xena(logger, owner) xm.session.add_chassis(chassis)