Skip to content

Commit

Permalink
Sonnar issue
Browse files Browse the repository at this point in the history
Cognitive Complexity.
  • Loading branch information
KacperPerschke committed Nov 5, 2024
1 parent 839c38a commit d200566
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 68 deletions.
27 changes: 22 additions & 5 deletions artifactory/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package artifactory

import (
"encoding/json"
"fmt"
"slices"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -69,11 +71,6 @@ type LicenseInfo struct {
ValidThrough string `json:"validThrough"`
LicensedTo string `json:"licensedTo"`
NodeId string
ValidSeconds int64 // It will be calculated in the ‘collector’ package.
}

func (l LicenseInfo) TypeNormalized() string {
return strings.ToLower(l.Type)
}

func (l LicenseInfo) IsOSS() bool {
Expand All @@ -88,6 +85,26 @@ func (l LicenseInfo) IsOSS() bool {
)
}

func (l LicenseInfo) TypeNormalized() string {
return strings.ToLower(l.Type)
}

func (l LicenseInfo) ValidSeconds() (int64, error) {
if l.IsOSS() {
return 0, nil
}
validThroughTime, err := time.Parse("Jan 2, 2006", l.ValidThrough)
if err != nil {
return 0, fmt.Errorf(
"unparsable ‘validThrough’ license field: %w",
err,
)
}
validThroughEpoch := validThroughTime.Unix()
timeNowEpoch := time.Now().Unix()
return validThroughEpoch - timeNowEpoch, nil
}

// FetchLicense makes the API call to license endpoint and returns LicenseInfo
func (c *Client) FetchLicense() (LicenseInfo, error) {
var licenseInfo LicenseInfo
Expand Down
26 changes: 26 additions & 0 deletions collector/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ func (e *Exporter) countUsersPerRealm(users []artifactory.User) realmUserCounts
return usersPerRealm
}

func (e *Exporter) exportAllSecurityMetrics(ch chan<- prometheus.Metric) error {
for metricName, metric := range securityMetrics {
switch metricName {
case "users":
err := e.exportUsersCount(metricName, metric, ch)
if err != nil {
return err
}
case "groups":
err := e.exportGroups(metricName, metric, ch)
if err != nil {
return err
}
case "certificates":
err := e.exportCertificates(metricName, metric, ch)
if err != nil {
return err
}
}
}
if err := e.exportReplications(ch); err != nil {
return err
}
return nil
}

func (e *Exporter) exportUsersCount(metricName string, metric *prometheus.Desc, ch chan<- prometheus.Metric) error {
// Fetch Artifactory Users
users, err := e.client.FetchUsers()
Expand Down
93 changes: 30 additions & 63 deletions collector/system.go
Original file line number Diff line number Diff line change
@@ -1,68 +1,9 @@
package collector

import (
"time"

"github.com/prometheus/client_golang/prometheus"

"github.com/peimanja/artifactory_exporter/artifactory"
)

func collectLicense(e *Exporter, ch chan<- prometheus.Metric) (artifactory.LicenseInfo, error) {
retErr := func(err error) (artifactory.LicenseInfo, error) {
return artifactory.LicenseInfo{}, err
}

license, err := e.client.FetchLicense()
if err != nil {
return retErr(err)
}

if !license.IsOSS() { // Some endpoints are only available commercially.
for metricName, metric := range securityMetrics {
switch metricName {
case "users":
err := e.exportUsersCount(metricName, metric, ch)
if err != nil {
return retErr(err)
}
case "groups":
err := e.exportGroups(metricName, metric, ch)
if err != nil {
return retErr(err)
}
case "certificates":
err := e.exportCertificates(metricName, metric, ch)
if err != nil {
return retErr(err)
}
}
}
if err := e.exportReplications(ch); err != nil {
return retErr(err)
}
}

licenseValidSeconds := func() int64 {
if license.IsOSS() {
return 0
}
validThroughTime, err := time.Parse("Jan 2, 2006", license.ValidThrough)
if err != nil {
e.logger.Warn(
"Couldn't parse Artifactory license ValidThrough",
"err", err.Error(),
)
return 0 // We deliberately ignore the error in order to maintain continuity.
}
validThroughEpoch := validThroughTime.Unix()
timeNowEpoch := time.Now().Unix()
return validThroughEpoch - timeNowEpoch
}
license.ValidSeconds = licenseValidSeconds()
return license, nil
}

func (e *Exporter) exportSystem(ch chan<- prometheus.Metric) error {
healthInfo, err := e.client.FetchHealth()
if err != nil {
Expand All @@ -82,7 +23,7 @@ func (e *Exporter) exportSystem(ch chan<- prometheus.Metric) error {
e.totalAPIErrors.Inc()
return err
}
licenseInfo, err := collectLicense(e, ch)
licenseInfo, err := e.client.FetchLicense()
if err != nil {
e.logger.Error(
"Couldn't scrape Artifactory when fetching system/license",
Expand All @@ -91,24 +32,50 @@ func (e *Exporter) exportSystem(ch chan<- prometheus.Metric) error {
e.totalAPIErrors.Inc()
return err
}
licenseValSec, err := licenseInfo.ValidSeconds()
if err != nil {
e.logger.Warn(
"Couldn't get Artifactory license validity",
"err", err.Error(),
) // To preserve the operation, we do nothing but log the event,
}

for metricName, metric := range systemMetrics {
switch metricName {
case "healthy":
ch <- prometheus.MustNewConstMetric(metric, prometheus.GaugeValue, convArtiToPromBool(healthInfo.Healthy), healthInfo.NodeId)
ch <- prometheus.MustNewConstMetric(
metric,
prometheus.GaugeValue,
convArtiToPromBool(healthInfo.Healthy),
healthInfo.NodeId,
)
case "version":
ch <- prometheus.MustNewConstMetric(metric, prometheus.GaugeValue, 1, buildInfo.Version, buildInfo.Revision, buildInfo.NodeId)
ch <- prometheus.MustNewConstMetric(
metric,
prometheus.GaugeValue,
1,
buildInfo.Version,
buildInfo.Revision,
buildInfo.NodeId,
)
case "license":
ch <- prometheus.MustNewConstMetric(
metric,
prometheus.GaugeValue,
float64(licenseInfo.ValidSeconds), // Prometheus expects a float type.
float64(licenseValSec), // Prometheus expects a float type.
licenseInfo.TypeNormalized(),
licenseInfo.LicensedTo,
licenseInfo.ValidThrough,
licenseInfo.NodeId,
)
}
}
if !licenseInfo.IsOSS() { // Some endpoints are only available commercially.
err := e.exportAllSecurityMetrics(ch)
if err != nil {
return err
}
}

return nil
}

0 comments on commit d200566

Please sign in to comment.