MI_Result MI_CALL Pull_SendStatusReport()

in LCM/dsc/engine/ca/CAInfrastructure/WebPullClient.c [2769:2951]


MI_Result MI_CALL Pull_SendStatusReport(_In_ LCMProviderContext *lcmContext,
                                                      _In_ MI_Instance *metaConfig,
                                                      _In_ MI_Instance *statusReport,
                                                      _In_ MI_Uint32 isStatusReport,
                                                      _Out_ MI_Uint32* getActionStatusCode,
                                                      _Outptr_result_maybenull_ MI_Instance **extendedError)
{

    MI_Result r = MI_RESULT_OK;
    const char *emptyString = "";
    MI_Char actionUrl[MAX_URL_LENGTH];
    char dataBuffer[10000];

    char * getActionStatus = NULL;
    long responseCode = 0;

    CURL *curl = NULL;
    CURLcode res = CURLE_OK;
    struct Chunk headerChunk;
    struct Chunk dataChunk;
    struct curl_slist *list = NULL;
    MI_Value managerInstances;
    MI_Value currentReportServer;
    MI_Value agentId;
    MI_Value serverURL;
    MI_Value endTime;
    MI_Uint32 flags;
    int i = 0;
    const char* commandFormat = NULL;
    const char* reportText = NULL;

    int bAtLeastOneReportSuccess = 0;

    r = DSC_MI_Instance_GetElement(metaConfig, MSFT_DSCMetaConfiguration_ReportManagers, &managerInstances, NULL, &flags, NULL);
    if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL))
    {
        // Unable to find report managers, don't report
        return MI_RESULT_OK;
    }

    r = GetSSLOptions(extendedError);
    if( r != MI_RESULT_OK)
    {
        return r;
    }

    r = DSC_MI_Instance_GetElement(metaConfig, "AgentId", &agentId, NULL, NULL, NULL);

    list = curl_slist_append(list, "Accept: application/json");
    list = curl_slist_append(list, "Content-Type: application/json; charset=utf-8");
    list = curl_slist_append(list, "ProtocolVersion: 2.0");

    for (i = 0; i < managerInstances.stringa.size; ++i)
    {
        r = MI_Instance_GetElement((MI_Instance*)managerInstances.stringa.data[i], MSFT_ServerURL_Name, &serverURL, NULL, NULL, NULL);

        r = MI_Instance_GetElement(statusReport, REPORTING_ENDTIME, &endTime, NULL, &flags, 0);
        if (r != MI_RESULT_OK || (flags & MI_FLAG_NULL) || (endTime.datetime.u.timestamp.year == 0))
        {
            // not the End report
            commandFormat =  DSC_SCRIPT_PATH "/StatusReport.sh %s StartTime";
            snprintf(dataBuffer, 10000, commandFormat, g_ConfigurationDetails.jobGuidString);
        }
        else
        {
            if (g_currentError[0] == '\0')
            {
                commandFormat =  DSC_SCRIPT_PATH "/StatusReport.sh %s EndTime";
                snprintf(dataBuffer, 10000, commandFormat, g_ConfigurationDetails.jobGuidString);
            }
            else
            {
                if (g_rnids == NULL)
                {
                    commandFormat =  DSC_SCRIPT_PATH "/StatusReport.sh %s EndTime \"%s\"";
                    snprintf(dataBuffer, 10000, commandFormat, g_ConfigurationDetails.jobGuidString, g_currentError);
                }
                else
                {
                    commandFormat =  DSC_SCRIPT_PATH "/StatusReport.sh %s EndTime \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" ";
                    snprintf(dataBuffer, 10000, commandFormat, g_ConfigurationDetails.jobGuidString, g_currentError, g_rnids->SourceInfo,
                             g_rnids->ModuleName, g_rnids->DurationInSeconds, g_rnids->InstanceName, g_rnids->StartDate, g_rnids->ResourceName,
                             g_rnids->ModuleVersion, g_rnids->RebootRequested, g_rnids->ResourceId, g_rnids->ConfigurationName, g_rnids->InDesiredState);
                    Destroy_StatusReport_RNIDS(g_rnids);
                    g_rnids = NULL;

                }
            }
        }

        reportText = RunCommand(dataBuffer);

        curl = curl_easy_init();
        if (!curl)
        {
            return GetCimMIError(MI_RESULT_FAILED, extendedError, ID_PULL_CURLFAILEDTOINITIALIZE);
        }

        r = SetGeneralCurlOptions(curl, extendedError);
        if (r != MI_RESULT_OK)
        {
            DSC_free(reportText);
            curl_easy_cleanup(curl);
            return r;
        }

        Snprintf(actionUrl, MAX_URL_LENGTH, "%s/Nodes(AgentId='%s')/SendReport", serverURL.string, agentId.string);
        curl_easy_setopt(curl, CURLOPT_URL, actionUrl);

        headerChunk.data = (char *)malloc(1);
        headerChunk.size = 0;
        dataChunk.data = (char *)malloc(1);
        dataChunk.size = 0;

        curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, reportText);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headerChunk);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dataChunk);

        res = curl_easy_setopt(curl, CURLOPT_SSLCERT, OAAS_CERTPATH);
        if (res != CURLE_OK)
        {
            curl_slist_free_all(list);
            curl_easy_cleanup(curl);
            return GetCimMIError(MI_RESULT_FAILED, extendedError, ID_PULL_CERTOPTS_NOT_SUPPORTED);
        }
        curl_easy_setopt(curl, CURLOPT_SSLKEY, OAAS_KEYPATH);

        res = curl_easy_perform(curl);

        if (res != CURLE_OK)
        {
            // Error on communication.  Go to next report.
            GetCimMIError2Params(MI_RESULT_FAILED, extendedError, ID_PULL_CURLPERFORMFAILED, actionUrl, curl_easy_strerror(res));

            curl_easy_cleanup(curl);
            DSC_free(reportText);
            free(headerChunk.data);
            free(dataChunk.data);
            continue;
        }

        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);

        if (responseCode != 200 && responseCode != 201 && responseCode != 204)
        {
            // Error on register
            MI_Char statusCodeValue[MAX_STATUSCODE_SIZE] = {0};
            Stprintf(statusCodeValue, MAX_STATUSCODE_SIZE, MI_T("%d"), responseCode);
            GetCimMIError2Params(MI_RESULT_FAILED, extendedError, ID_PULL_SERVERHTTPERRORCODEREGISTER, actionUrl, statusCodeValue);

            curl_easy_cleanup(curl);
            DSC_free(reportText);
            free(headerChunk.data);
            free(dataChunk.data);
            continue;
        }

        bAtLeastOneReportSuccess = 1;

        curl_easy_cleanup(curl);

        DSC_free(reportText);
        free(headerChunk.data);
        free(dataChunk.data);

    }

    curl_slist_free_all(list);

    if (bAtLeastOneReportSuccess == 1)
    {
        return MI_RESULT_OK;
    }
    else
    {
        MI_Char statusCodeValue[MAX_STATUSCODE_SIZE] = {0};
        Stprintf(statusCodeValue, MAX_STATUSCODE_SIZE, MI_T("%d"), responseCode);
        return GetCimMIError1Param(MI_RESULT_FAILED, extendedError, ID_PULL_REPORTINGFAILED, statusCodeValue);
    }
}