firehol/netdata

View on GitHub
src/go/plugin/go.d/modules/ceph/collect.go

Summary

Maintainability
A
40 mins
Test Coverage
// SPDX-License-Identifier: GPL-3.0-or-later

package ceph

import (
    "encoding/json"
    "errors"
    "fmt"
    "net/http"
    "slices"

    "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)

const precision = 1000

func (c *Ceph) collect() (map[string]int64, error) {
    mx := make(map[string]int64)

    if err := c.auth(); err != nil {
        return nil, err
    }

    if c.fsid == "" {
        fsid, err := c.getFsid()
        if err != nil {
            return nil, fmt.Errorf("failed to get fsid: %v", err)
        }
        c.fsid = fsid
        c.addClusterChartsOnce.Do(c.addClusterCharts)
    }

    if err := c.collectHealth(mx); err != nil {
        return nil, fmt.Errorf("failed to collect health: %v", err)
    }
    if err := c.collectOsds(mx); err != nil {
        return nil, fmt.Errorf("failed to collect osds: %v", err)
    }
    if err := c.collectPools(mx); err != nil {
        return nil, fmt.Errorf("failed to collect pools: %v", err)
    }

    return mx, nil
}

func (c *Ceph) auth() error {
    if c.token != "" {
        ok, err := c.authCheck()
        if err != nil {
            return err
        }
        if ok {
            return nil
        }
        c.token = ""
    }

    tok, err := c.authLogin()
    if err != nil {
        return err
    }
    c.token = tok

    return nil
}

func (c *Ceph) getFsid() (string, error) {
    req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiMonitor)
    if err != nil {
        return "", err
    }

    req.Header.Set("Accept", hdrAcceptVersion)
    req.Header.Set("Content-Type", hdrContentTypeJson)
    req.Header.Set("Authorization", "Bearer "+c.token)

    var resp struct {
        MonStatus struct {
            MonMap struct {
                FSID string `json:"fsid"`
            } `json:"monmap"`
        } `json:"mon_status"`
    }

    if err := c.webClient().RequestJSON(req, &resp); err != nil {
        return "", err
    }

    if resp.MonStatus.MonMap.FSID == "" {
        return "", errors.New("no fsid")
    }

    return resp.MonStatus.MonMap.FSID, nil
}

func (c *Ceph) webClient(statusCodes ...int) *web.Client {
    return web.DoHTTP(c.httpClient).OnNokCode(func(resp *http.Response) (bool, error) {
        if slices.Contains(statusCodes, resp.StatusCode) {
            return true, nil
        }
        var msg struct {
            Detail string `json:"detail"`
        }
        if err := json.NewDecoder(resp.Body).Decode(&msg); err == nil && msg.Detail != "" {
            return false, errors.New(msg.Detail)
        }
        return false, nil
    })
}