예제 #1
0
    def _get_members(self, url):

        data = self.request('GET', url, cmd='get_members')
        try:
            return data['Members']
        except KeyError as e:
            raise SelfServerException('Get KeyError %s' % e.args)
예제 #2
0
    def upload (self, method, resource, files, headers=None, cmd=''):

        httpheaders = headers or OpenBMCRest.headers
        url = resource
        if not url.startswith(HTTP_PROTOCOL):
            url = self.root_url + resource

        request_cmd = self._log_request(method, url, httpheaders, files=files, cmd=cmd)

        try:
            response = self.session.request_upload(method, url, httpheaders, files)
        except SelfServerException as e:
            self._print_error_log(e.message, cmd=cmd)
            raise
        try:
            data = json.loads(response)
        except ValueError:
            error = 'Received wrong format response when running command \'%s\': %s' % \
                    (request_cmd, response)
            self._print_error_log(error, cmd=cmd)
            raise SelfServerException(error)

        if data['message'] != '200 OK':
            error = 'Failed to upload update file %s : %s-%s' % \
                    (files, data['message'], \
                    ''.join(data['data']['description']))
            self._print_error_log(error, cmd=cmd)
            raise SelfClientException(error, code)

        self._print_record_log(data['message'], cmd=cmd) 

        return True
예제 #3
0
 def test_login_value_error(self):
     self.rf_rest.request = mock.Mock(side_effect=SelfServerException(
         'Received wrong format response: xxxxxx'))
     with pytest.raises(SelfServerException) as excinfo:
         self.rf_rest.login()
     assert excinfo.type == SelfServerException
     assert 'Received wrong format response:' in str(excinfo.value)
예제 #4
0
    def get_nic_netinfo(self, nic):

        path = RSPCONFIG_NETINFO_URL['get_nic_netinfo'].replace('#NIC#', nic)
        data = self.request('GET', path, cmd='get_nic_netinfo')

        try:
            netinfo = {}
            for k, v in data.items():
                dev, match, netid = k.partition("/ipv4/")
                if 'LinkLocal' in v["Origin"] or v["Address"].startswith(
                        "169.254"):
                    msg = "Found LinkLocal address %s for interface %s, Ignoring..." % (
                        v["Address"], dev)
                    self._print_record_log(msg, 'get_netinfo')
                    continue
                utils.update2Ddict(netinfo, netid, 'ip', v['Address'])
                utils.update2Ddict(netinfo, netid, 'ipsrc',
                                   v['Origin'].split('.')[-1])
                utils.update2Ddict(netinfo, netid, 'netmask',
                                   v['PrefixLength'])
                utils.update2Ddict(netinfo, netid, 'gateway', v['Gateway'])
            return netinfo
        except KeyError:
            error = 'Received wrong format response: %s' % data
            raise SelfServerException(error)
예제 #5
0
    def request (self, method, resource, headers=None, payload=None, timeout=30, cmd=''):

        httpheaders = headers or OpenBMCRest.headers
        url = resource
        if not url.startswith(HTTP_PROTOCOL):
            url = self.root_url + resource

        data = None
        if payload:
            data=json.dumps(payload)

        self._log_request(method, url, httpheaders, data=data, cmd=cmd)
        try:
            response = self.session.request(method, url, httpheaders, data=data, timeout=timeout)
            return self.handle_response(response, cmd=cmd)
        except SelfServerException as e:
            if cmd == 'login':
                e.message = "Login to BMC failed: Can't connect to {0} {1}.".format(e.host_and_port, e.detail_msg)
            else:
                e.message = 'BMC did not respond. ' \
                            'Validate BMC configuration and retry the command.'
            self._print_error_log(e.message, cmd)
            raise
        except ValueError:
            error = 'Received wrong format response: %s' % response
            self._print_error_log(error, cmd)
            raise SelfServerException(error)
예제 #6
0
    def request(self,
                method,
                resource,
                headers=None,
                payload=None,
                timeout=30,
                cmd=''):

        httpheaders = headers or OpenBMCRest.headers
        url = resource
        if not url.startswith(HTTP_PROTOCOL):
            url = self.root_url + resource

        data = None
        if payload:
            data = json.dumps(payload)

        self._log_request(method, url, httpheaders, data=data, cmd=cmd)
        try:
            response = self.session.request(method,
                                            url,
                                            httpheaders,
                                            data=data,
                                            timeout=timeout)
            return self.handle_response(response, cmd=cmd)
        except SelfServerException as e:
            e.message = 'Error: BMC did not respond. ' \
                        'Validate BMC configuration and retry the command.'
            self._print_record_log(e.message, cmd)
            raise
        except ValueError:
            error = 'Error: Received wrong format response: %s' % response
            self._print_record_log(error, cmd)
            raise SelfServerException(error)
예제 #7
0
    def get_sensor_info(self):

        sensor_data = self.request('GET', SENSOR_URL, cmd='get_sensor_info')
        try:
            sensor_dict = {}
            for k, v in sensor_data.items():
                if 'Unit' in v:
                    unit = v['Unit'].split('.')[-1]
                    if unit in SENSOR_UNITS:
                        label = k.split('/')[-1].replace('_', ' ').title()
                        value = v['Value']
                        scale = v['Scale']
                        value = value * pow(10, scale)
                        value = '{:g}'.format(value)
                        if unit not in sensor_dict:
                            sensor_dict[unit] = []
                        sensor_dict[unit].append(
                            '%s: %s %s' % (label, value, SENSOR_UNITS[unit]))
                elif 'units' in v and 'value' in v:
                    label = k.split('/')[-1]
                    value = v['value']
                    sensor_dict[label] = ['%s: %s' % (label, value)]

            return sensor_dict
        except KeyError:
            error = 'Received wrong format response: %s' % sensor_data
            raise SelfServerException(error)
예제 #8
0
    def parse_eventlog_data(self, eventlog_data):

        # Check if policy table file is there
        ras_event_mapping = {}
        if os.path.isfile(RAS_POLICY_TABLE):
            with open(RAS_POLICY_TABLE) as data_file:
                policy_hash = json.load(data_file)
                if policy_hash:
                    ras_event_mapping = policy_hash['events']
                else:
                    self.messager.info(RAS_POLICY_MSG)
                data_file.close()
        else:
            self.messager.info(RAS_POLICY_MSG)
        try:
            eventlog_dict = {}
            for key, value in sorted(eventlog_data.items()):
                id, event_log_line = self.parse_eventlog_data_record(
                    value, ras_event_mapping)
                if int(id) != 0:
                    eventlog_dict[str(id)] = event_log_line

            if not eventlog_dict:
                # Nothing was returned from BMC
                eventlog_dict['0'] = 'No attributes returned from the BMC.'

            return eventlog_dict
        except KeyError:
            error = 'Received wrong format response: %s' % eventlog_data
            raise SelfServerException(error)
예제 #9
0
 def test_request_login_connect_failed(self):
     login_data = { "UserName": self.rf_rest.username, "Password": self.rf_rest.password }
     self.rf_rest.session.request = mock.Mock(side_effect=SelfServerException('Login to BMC failed: Can\'t connect to'))
     with pytest.raises(SelfServerException) as excinfo:
         self.rf_rest.request('POST', self.session_url, headers=self.headers, payload=login_data, cmd='login')
     assert excinfo.type == SelfServerException
     assert 'Login to BMC failed: Can\'t connect to' in str(excinfo.value)
예제 #10
0
    def list_dump_info(self):

        dump_data = self.request('GET',
                                 DUMP_URLS['list'],
                                 cmd='list_dump_info')

        try:
            dump_dict = {}
            for key, value in dump_data.items():
                if 'Size' not in value or 'Elapsed' not in value:
                    continue

                key_id = int(key.split('/')[-1])
                timestamp = value['Elapsed']
                gen_time = time.strftime("%m/%d/%Y %H:%M:%S",
                                         time.localtime(timestamp))
                dump_dict.update(
                    {key_id: {
                        'Size': value['Size'],
                        'Generated': gen_time
                    }})

            return dump_dict
        except KeyError:
            error = 'Received wrong format response: %s' % dump_data
            raise SelfServerException(error)
예제 #11
0
    def reboot(self, optype='boot', **kw):

        node = kw['node']
        obmc = openbmc.OpenBMCRest(name=node,
                                   nodeinfo=kw['nodeinfo'],
                                   messager=self.callback,
                                   debugmode=self.debugmode,
                                   verbose=self.verbose)
        try:
            obmc.login()
            states = obmc.list_power_states()
            status = obmc.get_host_state(states)

            new_status = ''
            if optype == 'reset' and status in ['Off', 'chassison']:
                status = openbmc.RPOWER_STATES['Off']
                self.callback.info('%s: %s' % (node, status))
            else:
                if status not in ['Off', 'off']:
                    obmc.set_power_state('off')
                    self.callback.update_node_attributes(
                        'status', node, POWER_STATE_DB['off'])

                    off_flag = False
                    start_timeStamp = int(time.time())
                    for i in range(0, 30):
                        gevent.sleep(2)
                        try:
                            states = obmc.list_power_states()
                            status = obmc.get_host_state(states)
                            if openbmc.RPOWER_STATES.get(status) == 'off':
                                off_flag = True
                                break
                        except SelfServerException as e:
                            continue

                    end_timeStamp = int(time.time())

                    if not off_flag:
                        error = 'Error: Sent power-off command but state did not change ' \
                                 'to off after waiting %s seconds. (State= %s).' % (end_timeStamp - start_timeStamp, status)
                        raise SelfServerException(error)

                for i in range(0, 2):
                    try:
                        ret = obmc.set_power_state('on')
                        self.callback.update_node_attributes(
                            'status', node, POWER_STATE_DB['on'])
                        self.callback.info('%s: %s' % (node, 'reset'))
                        return
                    except SelfServerException as e:
                        self.callback.syslog('%s: %s' % (node, e.message))
                        gevent.sleep(1)
                        continue

                self.callback.error(e.message, node)

        except (SelfServerException, SelfClientException) as e:
            self.callback.error(e.message, node)
예제 #12
0
    def get_bmc_state(self):

        try:
            state = self.request('GET', BMC_URLS['state']['path'], cmd='get_bmc_state')
            return {'bmc': state.split('.')[-1]}
        except KeyError:
            error = 'Received wrong format response: %s' % state
            raise SelfServerException(error)
예제 #13
0
 def test_login_not_respond(self):
     self.rf_rest.request = mock.Mock(side_effect=SelfServerException(
         'BMC did not respond. Validate BMC configuration and retry the command.'
     ))
     with pytest.raises(SelfServerException) as excinfo:
         self.rf_rest.login()
     assert excinfo.type == SelfServerException
     assert 'BMC did not respond. Validate BMC configuration and retry the command.' in str(
         excinfo.value)
예제 #14
0
 def get_netinfo(self):
     data = self.request('GET',
                         RSPCONFIG_NETINFO_URL['get_netinfo'],
                         cmd="get_netinfo")
     try:
         netinfo = {}
         for k, v in data.items():
             if 'network/config' in k:
                 if 'HostName' in v:
                     netinfo["hostname"] = v["HostName"]
                 if 'DefaultGateway' in v:
                     netinfo["defaultgateway"] = v["DefaultGateway"]
                 continue
             dev, match, netid = k.partition("/ipv4/")
             if netid:
                 nicid = dev.split('/')[-1]
                 if nicid not in netinfo:
                     netinfo[nicid] = {}
                 if 'LinkLocal' in v["Origin"] or v["Address"].startswith(
                         "169.254"):
                     msg = "Found LinkLocal address %s for interface %s, Ignoring..." % (
                         v["Address"], dev)
                     self._print_record_log(msg, 'get_netinfo')
                     # Save Zero Conf information
                     netinfo[nicid]["zeroconf"] = v["Address"]
                     continue
                 if 'ip' in netinfo[nicid]:
                     msg = "%s: Another valid ip %s found." % (node,
                                                               v["Address"])
                     self._print_record_log(msg, 'get_netinfo')
                     del netinfo[nicid]
                     netinfo[
                         'error'] = 'Interfaces with multiple IP addresses are not supported'
                     break
                 utils.update2Ddict(netinfo, nicid, "ipsrc",
                                    v["Origin"].split('.')[-1])
                 utils.update2Ddict(netinfo, nicid, "netmask",
                                    v["PrefixLength"])
                 utils.update2Ddict(netinfo, nicid, "gateway", v["Gateway"])
                 utils.update2Ddict(netinfo, nicid, "ip", v["Address"])
                 utils.update2Ddict(netinfo, nicid, "ipobj", netid)
                 if dev in data:
                     info = data[dev]
                     utils.update2Ddict(netinfo, nicid, "vlanid",
                                        info.get("Id", "Disable"))
                     utils.update2Ddict(netinfo, nicid, "mac",
                                        info["MACAddress"])
                     ntpservers = None
                     tmp_ntpservers = ''.join(info["NTPServers"])
                     if tmp_ntpservers:
                         ntpservers = tmp_ntpservers
                     utils.update2Ddict(netinfo, nicid, "ntpservers",
                                        ntpservers)
         return netinfo
     except KeyError:
         error = 'Received wrong format response: %s' % data
         raise SelfServerException(error)
예제 #15
0
 def test_request_connect_failed(self):
     self.rf_rest.session.request = mock.Mock(side_effect=SelfServerException(
         'BMC did not respond. Validate BMC configuration and retry the command.'
     ))
     with pytest.raises(SelfServerException) as excinfo:
         self.rf_rest.request('GET', self.manager_url, headers=self.headers)
     assert excinfo.type == SelfServerException
     assert 'BMC did not respond. Validate BMC configuration and retry the command.' in str(
         excinfo.value)
예제 #16
0
    def get_systems_power_state(self):

        members = self._get_members(SYSTEMS_URL)
        target_url = members[0]['@odata.id']
        data = self.request('GET', target_url, cmd='get_systems_power_state')
        try:
            return data['PowerState']
        except KeyError as e:
            raise SelfServerException('Get KeyError %s' % e.args)
예제 #17
0
    def _get_boot_actions(self):

        members = self._get_members(SYSTEMS_URL)
        target_url = members[0]['@odata.id']
        data = self.request('GET', target_url, cmd='get_boot_actions')
        try:
            actions = data['Boot']['*****@*****.**']
        except KeyError as e:
            raise SelfServerException('Get KeyError %s' % e.args)

        return (target_url, actions) 
예제 #18
0
    def list_power_states(self):

        states = self.request('GET', RPOWER_URLS['state']['path'], cmd='list_power_states')
        #filter non used states
        try:
            host_stat = states[PROJECT_URL + '/state/host0']['CurrentHostState']
            chassis_stat = states[PROJECT_URL + '/state/chassis0']['CurrentPowerState']
            return {'host': host_stat.split('.')[-1], 'chassis': chassis_stat.split('.')[-1]}
        except KeyError:
            error = 'Received wrong format response: %s' % states
            raise SelfServerException(error)
예제 #19
0
    def _get_power_actions(self):

        members = self._get_members(SYSTEMS_URL)
        target_url = members[0]['@odata.id']
        data = self.request('GET', target_url, cmd='get_power_actions')
        try:
            actions = data['Actions'][system_reset_string][reset_type_string]
            target_url = data['Actions'][system_reset_string]['target']
        except KeyError as e:
            raise SelfServerException('Get KeyError %s' % e.args)

        return (target_url, actions)
예제 #20
0
    def get_beacon_info(self):

        beacon_data = self.request('GET', LEDS_URL, cmd='get_beacon_info')
        try:
            beacon_dict = {}
            for key, value in beacon_data.items():
                key_id = key.split('/')[-1]
                if key_id in LEDS_KEY_LIST:
                    beacon_dict[key_id] = value['State'].split('.')[-1]
            return beacon_dict
        except KeyError:
            error = 'Received wrong format response: %s' % beacon_data
            raise SelfServerException(error)
예제 #21
0
    def get_apis_values(self, key):
        attr_info = RSPCONFIG_APIS[key]
        if 'get_url' not in attr_info:
            raise SelfServerException("Reading %s failed, not url available" % key)
        get_url = attr_info['baseurl']+attr_info['get_url']

        method = 'GET'
        if 'get_method' in attr_info:
            method = attr_info['get_method']
        data = None
        if 'get_data' in attr_info:
            data={"data": attr_info['get_data']}
        return self.request(method, get_url, payload=data, cmd="get_%s" % key)
예제 #22
0
    def get_boot_state(self):

        members = self._get_members(SYSTEMS_URL)
        target_url = members[0]['@odata.id']
        data = self.request('GET', target_url, cmd='get_boot_state')
        try:
            boot_enable = data['Boot']['BootSourceOverrideEnabled']
            if boot_enable == 'Disabled':
                return 'boot override inactive'
            bootsource = data['Boot']['BootSourceOverrideTarget']
            return BOOTSOURCE_GET_STATE.get(bootsource, bootsource)
        except KeyError as e:
            raise SelfServerException('Get KeyError %s' % e.args)
예제 #23
0
    def set_apis_values(self, key, value):
        attr_info = RSPCONFIG_APIS[key]
        if 'set_url' not in attr_info:
            raise SelfServerException("config %s failed, not url available" % key)
        set_url = attr_info['baseurl']+attr_info['set_url']
        if 'attr_values' in attr_info and value in attr_info['attr_values']:
            data = attr_info['attr_values'][value]
        else:
            data = value

        method = 'PUT'
        if key == 'powersupplyredundancy':
            method = 'POST'
        self.request(method, set_url, payload={"data": data}, cmd="set_%s" % key)
예제 #24
0
    def get_inventory_info(self, inventory_type):

        inventory_data = self.request('GET',
                                      INVENTORY_URLS[inventory_type],
                                      cmd='get_inventory_info')
        try:
            inventory_dict = {}
            if inventory_type == 'model' or inventory_type == 'serial':
                # The format of returned data for model and serial a different from other inventory types
                inventory_dict['SYSTEM'] = []
                for key, value in inventory_data.items():
                    inventory_dict['SYSTEM'].append('%s %s : %s' %
                                                    ("SYSTEM", key, value))

                return inventory_dict

            for key, value in inventory_data.items():
                if 'Present' not in value:
                    logger.debug('Not "Present" for %s' % key)
                    continue

                key_list = key.split('/')
                try:
                    key_id = key_list[-1]
                    key_tmp = key_list[-2]
                except IndexError:
                    logger.debug('IndexError (-2) for %s' % key)
                    continue

                key_type_list = [x for x in key_id if x not in '0123456789']
                key_type = ''.join(key_type_list).upper()

                if key_type == 'CORE':
                    key_type = 'CPU'
                    source = '%s %s' % (key_tmp, key_id)
                else:
                    source = key_id

                if key_type not in inventory_dict:
                    inventory_dict[key_type] = []

                for (sub_key, v) in value.items():
                    inventory_dict[key_type].append(
                        '%s %s : %s' % (source.upper(), sub_key, v))

            return inventory_dict
        except KeyError:
            error = 'Received wrong format response: %s' % inventory_data
            raise SelfServerException(error)
예제 #25
0
    def handle_response(self, resp, cmd=''):

        code = resp.status_code
        if code == requests.codes.bad_gateway:
            error = "(Verify REST server is running on the BMC)"
            self._print_error_log(error, cmd)
            raise SelfServerException(code, error, host_and_port=self.bmcip)
        data = resp.json()  # it will raise ValueError
        if code != requests.codes.ok:
            description = ''.join(data['data']['description'])
            error = '[%d] %s' % (code, description)
            self._print_error_log(error, cmd)
            raise SelfClientException(error, code)

        self._print_record_log(data['message'], cmd)
        return data['data']
예제 #26
0
    def get_boot_state(self):

        state = self.request('GET', BOOTSOURCE_URLS['get']['path'], cmd='get_boot_state')
        try:
            one_time_path = PROJECT_URL + '/control/host0/boot/one_time'
            one_time_enabled =  state[one_time_path]['Enabled']
            if one_time_enabled:
                boot_source = state[one_time_path]['BootSource'].split('.')[-1]
            else:
                boot_source = state[PROJECT_URL + '/control/host0/boot']['BootSource'].split('.')[-1]

            error = 'Can not get valid rsetboot status, the data is %s' % boot_source
            boot_state = BOOTSOURCE_GET_STATE.get(boot_source.split('.')[-1], error)
            return boot_state
        except KeyError:
            error = 'Received wrong format response: %s' % states
            raise SelfServerException(error)
예제 #27
0
    def handle_response(self, resp, cmd=''):

        data = resp.json()
        code = resp.status_code

        if code != requests.codes.ok and code != requests.codes.created:

            description = ''.join(
                data['error']['@Message.ExtendedInfo'][0]['Message'])
            error = '[%d] %s' % (code, description)
            self._print_error_log(error, cmd)
            raise SelfClientException(error, code)

        if cmd == 'login' and not 'X-Auth-Token' in resp.headers:
            raise SelfServerException(
                'Login Failed: Did not get Session Token from response')

        self._print_record_log('%s %s' % (code, data['Name']), cmd)
        return data
예제 #28
0
    def _get_power_actions(self):

        members = self._get_members(SYSTEMS_URL)
        target_url = members[0]['@odata.id']
        data = self.request('GET', target_url, cmd='get_power_actions')

        try:
            actions_dict = data['Actions'][system_reset_string]
            target_url = actions_dict['target']
            if reset_action_string in actions_dict:
                action_info = self.request('GET',
                                           actions_dict[reset_action_string],
                                           cmd='get_power_actions')
                actions = action_info['Parameters'][0]['AllowableValues']
            else:
                actions = actions_dict[reset_type_string]
        except KeyError as e:
            raise SelfServerException('Get KeyError %s' % e.args)

        return (target_url, actions)
예제 #29
0
    def get_inventory_info(self):

        inventory_data = self.request('GET',
                                      INVENTORY_URL,
                                      cmd='get_inventory_info')
        try:
            inverntory_dict = {}
            for key, value in inventory_data.items():
                if 'Present' not in value:
                    logger.debug('Not "Present" for %s' % key)
                    continue

                key_list = key.split('/')
                try:
                    key_id = key_list[-1]
                    key_tmp = key_list[-2]
                except IndexError:
                    logger.debug('IndexError (-2) for %s' % key)
                    continue

                key_type = filter(lambda x: x not in '0123456789',
                                  key_id).upper()

                if key_type == 'CORE':
                    key_type = 'CPU'
                    source = '%s %s' % (key_tmp, key_id)
                else:
                    source = key_id

                if key_type not in inverntory_dict:
                    inverntory_dict[key_type] = []

                for (sub_key, v) in value.items():
                    inverntory_dict[key_type].append(
                        '%s %s : %s' % (source.upper(), sub_key, v))

            return inverntory_dict
        except KeyError:
            error = 'Error: Received wrong format response: %s' % inventory_data
            raise SelfServerException(error)