Skip to content
This repository has been archived by the owner on Jul 18, 2024. It is now read-only.

Commit

Permalink
rebase from main (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alva8756 authored May 7, 2024
1 parent 7a75068 commit c7c62bc
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 48 deletions.
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ toolchain go1.22.2

require (
github.com/bmc-toolbox/common v0.0.0-20240426155832-c9882dbabcca
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/equinix-labs/otel-init-go v0.0.9
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.6.0
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/metal-toolbox/alloy v0.3.3-0.20240415055734-d09250fed38a
github.com/metal-toolbox/fleetdb v0.17.3
github.com/metal-toolbox/rivets v1.0.4
Expand All @@ -18,8 +20,10 @@ require (
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.9.0
go.hollow.sh/toolbox v0.6.3
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0
go.uber.org/mock v0.4.0
go.uber.org/zap v1.27.0
golang.org/x/oauth2 v0.19.0
)

require (
Expand All @@ -33,6 +37,7 @@ require (
github.com/cockroachdb/cockroach-go/v2 v2.3.7 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/ericlagergren/decimal v0.0.0-20240411145413-00de7ca16731 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/friendsofgo/errors v0.9.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
Expand All @@ -50,6 +55,7 @@ require (
github.com/gosimple/unidecode v1.0.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down Expand Up @@ -77,6 +83,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/pquerna/cachecontrol v0.2.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.53.0 // indirect
github.com/prometheus/procfs v0.14.0 // indirect
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go/v2 v2.3.7 h1:nq5GYDuA2zIR/kdLkVLTg7oHTw0UbGU9RWpC+OZVYYU=
github.com/cockroachdb/cockroach-go/v2 v2.3.7/go.mod h1:1wNJ45eSXW9AnOc3skntW9ZUZz6gxrQK3cOj3rK+BC8=
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
Expand Down Expand Up @@ -167,6 +169,8 @@ github.com/ericlagergren/decimal v0.0.0-20240411145413-00de7ca16731/go.mod h1:M9
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
Expand Down Expand Up @@ -342,9 +346,13 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
Expand All @@ -353,6 +361,8 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
Expand Down Expand Up @@ -487,6 +497,8 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
Expand Down Expand Up @@ -565,6 +577,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
Expand Down
3 changes: 3 additions & 0 deletions helm/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ data:
config.yaml: |
listen_address: 0.0.0.0:{{ .Values.app.containerPort }}
developer_mode: true
fleetdb:
endpoint: {{ .Values.fleetdb.env.endpoint }}
disable_oauth: true
8 changes: 7 additions & 1 deletion helm/values.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
---
image:
repo: localhost:5001
repo: "localhost:5001/component-inventory"
tag: latest
pullPolicy: Always

app:
name: component-inventory
serviceName: inventory-api
configPath: /etc/cis
livenessURI: /_health/liveness
containerPort: 7500

fleetdb:
env:
endpoint: http://fleetdb:8000
disable_oauth: true
57 changes: 51 additions & 6 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (a *App) ContextDone() bool {
// LogRunningConfig does exactly what it says on the tin. It is only a side-effect.
func (a *App) LogRunningConfig() {
a.Log.Info("running configuration",
zap.String("fleetdb.address", a.Cfg.FleetDBAddress),
zap.String("fleetdb.address", a.Cfg.FleetDBAPIOptions.Endpoint),
zap.String("listen.address", a.Cfg.ListenAddress),
zap.Bool("developer.mode", a.Cfg.DeveloperMode),
// do something for the JWTAuthConfig
Expand Down Expand Up @@ -107,13 +107,14 @@ func LoadConfiguration(cfgFile string) (*Configuration, error) {
return nil, errors.New("listen address not set")
}

if cfg.FleetDBAddress == "" {
if cfg.FleetDBAPIOptions.Endpoint == "" {
return nil, errors.New("fleetdb endpoint not set")
}

return cfg, nil
}

// nolint:gocyclo // parameter validation is cyclomatic
func envVarOverrides(v *viper.Viper, cfg *Configuration) error {
if addr := v.GetString("listen.address"); addr != "" {
cfg.ListenAddress = addr
Expand All @@ -123,15 +124,59 @@ func envVarOverrides(v *viper.Viper, cfg *Configuration) error {
cfg.DeveloperMode = true
}

if dbToken := v.GetString("fleetdb.access.token"); dbToken != "" {
cfg.FleetDBToken = dbToken
}

// sanity checks
if cfg.ListenAddress == "" {
return errors.New("no listen address set")
}

if v.GetString("fleetdb.disable.oauth") != "" {
cfg.FleetDBAPIOptions.DisableOAuth = v.GetBool("fleetdb.disable.oauth")
}

if cfg.FleetDBAPIOptions.DisableOAuth {
return nil
}

if v.GetString("fleetdb.oidc.issuer.endpoint") != "" {
cfg.FleetDBAPIOptions.OidcIssuerEndpoint = v.GetString("fleetdb.oidc.issuer.endpoint")
}

if cfg.FleetDBAPIOptions.OidcAudienceEndpoint == "" {
return errors.New("fleetdb oidc.audience.endpoint not defined")
}

if v.GetString("fleetdb.oidc.audience.endpoint") != "" {
cfg.FleetDBAPIOptions.OidcAudienceEndpoint = v.GetString("fleetdb.oidc.audience.endpoint")
}

if cfg.FleetDBAPIOptions.OidcAudienceEndpoint == "" {
return errors.New("fleetdb oidc.audience.endpoint not defined")
}

if v.GetString("fleetdb.oidc.client.secret") != "" {
cfg.FleetDBAPIOptions.OidcClientSecret = v.GetString("fleetdb.oidc.client.secret")
}

if cfg.FleetDBAPIOptions.OidcClientSecret == "" {
return errors.New("fleetdb oidc.client.secret not defined")
}

if v.GetString("fleetdb.oidc.client.id") != "" {
cfg.FleetDBAPIOptions.OidcClientID = v.GetString("fleetdb.oidc.client.id")
}

if cfg.FleetDBAPIOptions.OidcClientID == "" {
return errors.New("fleetdb oidc.client.id not defined")
}

if v.GetString("fleetdb.oidc.client.scopes") != "" {
cfg.FleetDBAPIOptions.OidcClientScopes = v.GetStringSlice("fleetdb.oidc.client.scopes")
}

if len(cfg.FleetDBAPIOptions.OidcClientScopes) == 0 {
return errors.New("fleetdb oidc.client.scopes not defined")
}

return nil
}

Expand Down
20 changes: 15 additions & 5 deletions internal/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ import (
)

type Configuration struct {
ListenAddress string `mapstructure:"listen_address"`
DeveloperMode bool `mapstructure:"developer_mode"`
JWTAuth []ginjwt.AuthConfig `mapstructure:"ginjwt_auth"`
FleetDBAddress string `mapstructure:"fleetdb_address"`
FleetDBToken string `mapstructure:"fleetdb_token"`
ListenAddress string `mapstructure:"listen_address"`
DeveloperMode bool `mapstructure:"developer_mode"`
JWTAuth []ginjwt.AuthConfig `mapstructure:"ginjwt_auth"`
FleetDBAPIOptions FleetDBAPIOptions `mapstructure:"fleetdb"`
}

// https://github.com/metal-toolbox/fleetdb
type FleetDBAPIOptions struct {
Endpoint string `mapstructure:"endpoint"`
OidcIssuerEndpoint string `mapstructure:"oidc_issuer_endpoint"`
OidcAudienceEndpoint string `mapstructure:"oidc_audience_endpoint"`
OidcClientSecret string `mapstructure:"oidc_client_secret"`
OidcClientID string `mapstructure:"oidc_client_id"`
OidcClientScopes []string `mapstructure:"oidc_client_scopes"`
DisableOAuth bool `mapstructure:"disable_oauth"`
}
70 changes: 64 additions & 6 deletions internal/fleetdb/fleetdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ package internalfleetdb

import (
"context"
"net/url"
"time"

common "github.com/bmc-toolbox/common"
oidc "github.com/coreos/go-oidc"
"github.com/google/uuid"
"github.com/hashicorp/go-retryablehttp"
"github.com/metal-toolbox/component-inventory/internal/app"
"github.com/metal-toolbox/component-inventory/internal/inventoryconverter"
fleetdb "github.com/metal-toolbox/fleetdb/pkg/api/v1"
rivets "github.com/metal-toolbox/rivets/types"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.uber.org/zap"
"golang.org/x/oauth2"
"golang.org/x/oauth2/clientcredentials"
)

type Client interface {
Expand All @@ -19,17 +26,18 @@ type Client interface {
GetInventoryConverter() *inventoryconverter.InventoryConverter
}

// connectionTimeout is the maximum amount of time spent on each http connection to FleetDBClient.
var connectionTimeout = 30 * time.Second

// Creates a new Client, with reasonable defaults
func NewFleetDBClient(_ context.Context, cfg *app.Configuration) (Client, error) {
client, err := fleetdb.NewClient(cfg.FleetDBAddress, nil)
func NewFleetDBClient(ctx context.Context, cfg *app.Configuration) (Client, error) {
fleetDBOpts := &cfg.FleetDBAPIOptions
client, err := getFleetDBAPIClient(ctx, fleetDBOpts)

if err != nil {
return nil, err
}

if cfg.FleetDBToken != "" {
client.SetToken(cfg.FleetDBToken)
}

slugs := make(map[string]bool)
serverComponentTypes := common.ComponentTypes()
for _, ct := range serverComponentTypes {
Expand All @@ -42,6 +50,56 @@ func NewFleetDBClient(_ context.Context, cfg *app.Configuration) (Client, error)
}, nil
}

func getFleetDBAPIClient(ctx context.Context, cfg *app.FleetDBAPIOptions) (*fleetdb.Client, error) {
if cfg.DisableOAuth {
return fleetdb.NewClientWithToken("fake", cfg.Endpoint, nil)
}

// init retryable http client
retryableClient := retryablehttp.NewClient()

// set retryable HTTP client to be the otel http client to collect telemetry
retryableClient.HTTPClient = otelhttp.DefaultClient

// setup oidc provider
provider, err := oidc.NewProvider(ctx, cfg.OidcIssuerEndpoint)
if err != nil {
return nil, err
}

clientID := "component-inventory"

if cfg.OidcClientID != "" {
clientID = cfg.OidcClientID
}

// setup oauth configuration
oauthConfig := clientcredentials.Config{
ClientID: clientID,
ClientSecret: cfg.OidcClientSecret,
TokenURL: provider.Endpoint().TokenURL,
Scopes: cfg.OidcClientScopes,
EndpointParams: url.Values{"audience": []string{cfg.OidcAudienceEndpoint}},
// with this the oauth client spends less time identifying the client grant mechanism.
AuthStyle: oauth2.AuthStyleInParams,
}

// wrap OAuth transport, cookie jar in the retryable client
oAuthclient := oauthConfig.Client(ctx)

retryableClient.HTTPClient.Transport = oAuthclient.Transport
retryableClient.HTTPClient.Jar = oAuthclient.Jar

httpClient := retryableClient.StandardClient()
httpClient.Timeout = connectionTimeout

return fleetdb.NewClientWithToken(
cfg.OidcClientSecret,
cfg.Endpoint,
httpClient,
)
}

type fleetDBClient struct {
client *fleetdb.Client
inventoryConverterInstance *inventoryconverter.InventoryConverter
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/client/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (c Error) Error() string {
// RequestError is returned when the client gets an error while performing a request.
type RequestError struct {
Message string `json:"message"`
StatusCode int `json:"statusCode"`
StatusCode int `json:"status_code"`
}

// Error returns the RequestError in string format
Expand Down
27 changes: 0 additions & 27 deletions pkg/api/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,4 @@ const (
ComponentsEndpoint = "/components"
InbandInventoryEndpoint = "/inventory/in-band"
OutofbandInventoryEndpoint = "/inventory/out-of-band"

// server service attribute to look up the BMC IP Address in
BmcAttributeNamespace = "sh.hollow.bmc_info"

// server server service BMC address attribute key found under the bmcAttributeNamespace
BmcIPAddressAttributeKey = "address"

// serverservice namespace prefix the data is stored in.
ServerServiceNSPrefix = "sh.hollow.alloy"

// server vendor, model attributes are stored in this namespace.
ServerVendorAttributeNS = ServerServiceNSPrefix + ".server_vendor_attributes"

// additional server metadata are stored in this namespace.
ServerMetadataAttributeNS = ServerServiceNSPrefix + ".server_metadata_attributes"

// errors that occurred when connecting/collecting inventory from the bmc are stored here.
ServerBMCErrorsAttributeNS = ServerServiceNSPrefix + ".server_bmc_errors"

// server service server serial attribute key
ServerSerialAttributeKey = "serial"

// server service server model attribute key
ServerModelAttributeKey = "model"

// server service server vendor attribute key
ServerVendorAttributeKey = "vendor"
)
Loading

0 comments on commit c7c62bc

Please sign in to comment.