metal/mtce/src/maintenance/mtcVimApi.cpp

297 lines
9.6 KiB
C++

/*
* Copyright (c) 2013, 2016, 2023 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform Controller Maintenance
* Access to Service Manager via REST API Interface.
*
*/
#ifdef __AREA__
#undef __AREA__
#endif
#define __AREA__ "vim"
using namespace std;
#include "nodeBase.h" /* for ... common definitions */
#include "nodeUtil.h" /* for ... common utilities */
#include "nodeClass.h" /* for ... maintenance class nodeLinkClass */
#include "mtcVimApi.h" /* for ... this module header */
#include "jsonUtil.h" /* for ... jsonUtil_get_key_val */
/*******************************************/
/* Internal Private utilities and handlers */
/*******************************************/
/* The handles the inventory PATCH request's response message */
int mtcVimApi_handler ( libEvent & event )
{
jlog ("%s Response:%s\n", event.log_prefix.c_str(), event.response.c_str());
return (PASS);
}
string nodeLinkClass::mtcVimApi_state_get ( string hostname, int & http_status_code )
{
string payload = "" ;
/* payload
* {
* { "availability":"",
* "operational":"",
* "administrative":"",
* "data_ports_oper:"",
* "data_ports_avail:"",
* "subfunction_oper:"",
* "subfunction_avail:"",
* },
* "uuid":"",
* "hostname":"",
* "subfunctions":"",
* "personality":""
* }
**/
nodeLinkClass::node * node_ptr = getNode ( hostname ) ;
if ( !node_ptr )
{
payload.append (" \"status\" : \"fail\"");
payload.append (",\"reason\" : \"not found\"");
payload.append (",\"action\" : \"undetermined\"");
payload.append ("}");
http_status_code = HTTP_NOTFOUND ;
return ( payload );
}
#ifdef WANT_FIT_TESTING
static const char * fit_file = "/var/run/fit/mtcVimApi_state_get";
if ( daemon_want_fit ( FIT_CODE__READ_JSON_FROM_FILE, hostname, "mtcVimApi_state_get"))
{
if ( daemon_is_file_present (fit_file) )
{
payload = daemon_read_file(fit_file);
ilog("%s FIT Json: %s", hostname.c_str(), payload.c_str());
return (payload);
}
else
{
slog("%s FIT file %s not found ; aborting fit", hostname.c_str(), fit_file);
}
}
#endif
payload = ("{\"") ;
payload.append (MTC_JSON_INV_ADMIN);
payload.append ("\":\"");
payload.append (adminState_enum_to_str(node_ptr->adminState));
payload.append ("\",\"");
payload.append (MTC_JSON_INV_OPER);
payload.append ("\":\"");
payload.append (operState_enum_to_str(node_ptr->operState ));
payload.append ("\",\"");
payload.append (MTC_JSON_INV_AVAIL);
payload.append ("\":\"");
payload.append (availStatus_enum_to_str(node_ptr->availStatus ));
payload.append ("\",");
/* Only add these feilds if we have received messages from the vswitch
* The avail state is defaulted to offline */
if ( node_ptr->availStatus_dport != MTC_AVAIL_STATUS__OFFDUTY )
{
payload.append ("\"data_ports_oper\":\"");
payload.append (operState_enum_to_str(node_ptr->operState_dport));
payload.append ("\",");
payload.append ("\"data_ports_avail\":\"");
payload.append (availStatus_enum_to_str(node_ptr->availStatus_dport));
payload.append ("\",");
}
payload.append ("\"subfunction_oper\":\"");
payload.append (operState_enum_to_str(node_ptr->operState_subf));
payload.append ("\",");
payload.append ("\"subfunction_avail\":\"");
payload.append (availStatus_enum_to_str(node_ptr->availStatus_subf));
payload.append ("\"},");
payload.append ("\"hostname\":\"");
payload.append (hostname);
payload.append ("\",");
payload.append ("\"uuid\":\"");
payload.append (node_ptr->uuid);
payload.append ("\",");
payload.append ("\"subfunctions\":\"");
payload.append (node_ptr->functions);
payload.append ("\",");
payload.append ("\"personality\":\"");
payload.append (node_ptr->function_str);
payload.append ("\"}");
return (payload);
}
/* curl -i -X GET -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'User-Agent: vim/1.0' http://localhost:2112/v1/systems */
int nodeLinkClass::mtcVimApi_system_info ( string & response )
{
int http_status_code = HTTP_OK ;
if ( hosts )
response = "{\"hosts\":[" ;
for ( struct node * ptr = head ; ; ptr = ptr->next )
{
dlog ("%s %6d %s\n", ptr->uuid.c_str(), ptr->uptime, ptr->hostname.c_str() );
if ( ptr->add_completed == true )
{
response.append("{\"uuid\":\"");
response.append(ptr->uuid);
response.append("\",\"hostname\":\"");
response.append(ptr->hostname);
response.append("\",\"uptime\":");
response.append(itos(ptr->uptime));
response.append("}");
if (( ptr->next != NULL ) && ( ptr != tail ))
{
response.append(",");
}
}
else
{
http_status_code = MTC_HTTP_ACCEPTED ;
}
if (( ptr->next == NULL ) || ( ptr == tail ))
{
break ;
}
}
response.append("]}");
jlog ("Response: %s", response.c_str() );
return (http_status_code);
}
/**
* Name : mtcVimApi_state_change
*
* Description: Submit any of the following requests to
* the VIM against the specified hostname.
*
* Operations:
*
* VIM Commands - Descriptions
* ------------- ------------------------------
* HOST_DISABLE - Inform VIM that this host is now Mtce-Disabled
* HOST_ENABLE - Inform VIM that this host is now Mtce-Enabled
* HOST_FAIL - Inform VIM that this host has failed and
* undergoing auto recovery
*
*/
int nodeLinkClass::mtcVimApi_state_change ( struct nodeLinkClass::node * node_ptr,
libEvent_enum request,
int retries )
{
int http_status_code = HTTP_OK ;
string type ="host" ;
mtcHttpUtil_event_init ( &node_ptr->httpReq,
node_ptr->hostname,
"mtcVimApi_state_change",
hostUtil_getServiceIp ( SERVICE_VIM ),
hostUtil_getServicePort ( SERVICE_VIM ));
/* Set the host context */
node_ptr->httpReq.hostname = node_ptr->hostname ;
node_ptr->httpReq.uuid = node_ptr->uuid;
node_ptr->httpReq.cur_retries = 0 ;
node_ptr->httpReq.max_retries = retries ;
node_ptr->httpReq.active = true ;
node_ptr->httpReq.noncritical = false ;
switch ( request )
{
case VIM_HOST_DISABLED:
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = VIM_HOST__DISABLED ;
break ;
case VIM_HOST_ENABLED:
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = VIM_HOST__ENABLED ;
break ;
case VIM_HOST_OFFLINE:
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = VIM_HOST__OFFLINE;
break ;
case VIM_HOST_FAILED:
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = VIM_HOST__FAILED ;
break ;
case VIM_DPORT_OFFLINE:
type = "data port";
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = "offline" ;
break ;
case VIM_DPORT_CLEARED:
type = "data port";
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = "clear" ;
break ;
case VIM_DPORT_DEGRADED:
type = "data port";
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = "major" ;
break ;
case VIM_DPORT_FAILED:
type = "data port";
node_ptr->httpReq.request = request ;
node_ptr->httpReq.operation = "critical" ;
break ;
default:
return (FAIL_BAD_PARM) ;
}
node_ptr->httpReq.payload = "{\"state-change\": " ;
node_ptr->httpReq.payload.append (mtcVimApi_state_get ( node_ptr->hostname , http_status_code ));
#ifdef WANT_FIT_TESTING
static const char * fit_file = "/var/run/fit/mtcVimApi_state_change";
if ( daemon_want_fit ( FIT_CODE__READ_JSON_FROM_FILE, node_ptr->hostname, "mtcVimApi_state_change" ))
{
if ( daemon_is_file_present (fit_file) )
{
node_ptr->httpReq.payload = daemon_read_file(fit_file);
ilog("%s FIT Json: %s", node_ptr->hostname.c_str(), node_ptr->httpReq.payload.c_str());
}
else
{
slog("%s FIT file %s not found ; aborting fit", node_ptr->hostname.c_str(), fit_file);
}
}
#endif
if (( request == VIM_HOST_FAILED ) || ( request == VIM_DPORT_FAILED ))
{
wlog ("%s %s\n", node_ptr->hostname.c_str(), node_ptr->httpReq.payload.c_str());
}
else
{
ilog ("%s sending '%s' state change to vim (%s)",
node_ptr->hostname.c_str(),
type.c_str(),
node_ptr->httpReq.operation.c_str());
dlog ("%s %s\n", node_ptr->hostname.c_str(), node_ptr->httpReq.payload.c_str());
}
return(workQueue_enqueue( node_ptr->httpReq));
}