Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC provider #343

Merged
merged 27 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b69d318
WIP: Add RPC provider:
jacobweinstock Aug 12, 2023
d428e47
Update linter version
jacobweinstock Aug 12, 2023
b1fcbab
Reorganize the RPC provider:
jacobweinstock Aug 14, 2023
f43dbfc
Simplify rpc code again:
jacobweinstock Sep 1, 2023
cc64911
Add log message if RPC configs merge fails:
jacobweinstock Sep 1, 2023
7a7f906
Add initial doc.go for rpc package:
jacobweinstock Sep 1, 2023
b07c6a5
Clean up go.mod
jacobweinstock Sep 1, 2023
efac18f
Revert changes to the client test:
jacobweinstock Sep 1, 2023
aa6ff78
Add code comments
jacobweinstock Sep 1, 2023
ce51678
Add experimental RequestPayload embedding:
jacobweinstock Sep 1, 2023
6fddc6c
Add RPC to supported BMC interfaces in readme
jacobweinstock Sep 1, 2023
121a59a
Fix code comment
jacobweinstock Sep 5, 2023
dbb08da
Invert nil check, be sure to close response body:
jacobweinstock Sep 6, 2023
ac389b6
Move registering the RPC to its own func
jacobweinstock Sep 6, 2023
e961fc4
Move http client to the top level:
jacobweinstock Sep 6, 2023
2ecfd71
Rename Config -> Provider:
jacobweinstock Sep 6, 2023
655d6ee
Update receiver variable:
jacobweinstock Sep 6, 2023
588de30
Update code comment for IncludedPayloadHeaders:
jacobweinstock Sep 8, 2023
7c6461a
Remove body.Close on passed in *http.Response:
jacobweinstock Sep 8, 2023
8c7de93
Fix some linting issues
jacobweinstock Sep 8, 2023
45e4d38
Add max allowed response content size:
jacobweinstock Sep 8, 2023
cc82aad
Error on unknown content size:
jacobweinstock Sep 8, 2023
ffe1702
Add an example for the configuring and using the RPC provider:
jacobweinstock Sep 11, 2023
55d4044
Check response in Open method:
jacobweinstock Sep 11, 2023
4d9b3c7
Add doc comment on HMAC
jacobweinstock Sep 11, 2023
6440d17
Copy req/resp bodies to buffers:
jacobweinstock Sep 11, 2023
61c88e3
Be more defensive with the response body:
jacobweinstock Sep 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ bmclib v2 is a library to abstract interacting with baseboard management control
- [IPMItool](https://github.com/bmc-toolbox/bmclib/tree/main/providers/ipmitool)
- [Intel AMT](https://github.com/bmc-toolbox/bmclib/tree/main/providers/intelamt)
- [Asrockrack](https://github.com/bmc-toolbox/bmclib/tree/main/providers/asrockrack)
- [RPC](providers/rpc/)

## Installation

Expand Down
27 changes: 27 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ package bmclib

import (
"context"
"fmt"
"io"
"net/http"
"sync"
"time"

"dario.cat/mergo"
"github.com/bmc-toolbox/bmclib/v2/bmc"
"github.com/bmc-toolbox/bmclib/v2/internal/httpclient"
"github.com/bmc-toolbox/bmclib/v2/providers/asrockrack"
"github.com/bmc-toolbox/bmclib/v2/providers/dell"
"github.com/bmc-toolbox/bmclib/v2/providers/intelamt"
"github.com/bmc-toolbox/bmclib/v2/providers/ipmitool"
"github.com/bmc-toolbox/bmclib/v2/providers/redfish"
"github.com/bmc-toolbox/bmclib/v2/providers/rpc"
"github.com/bmc-toolbox/bmclib/v2/providers/supermicro"
"github.com/bmc-toolbox/common"
"github.com/go-logr/logr"
Expand Down Expand Up @@ -58,6 +61,7 @@ type providerConfig struct {
intelamt intelamt.Config
dell dell.Config
supermicro supermicro.Config
rpc rpc.Provider
}

// NewClient returns a new Client struct
Expand Down Expand Up @@ -90,6 +94,7 @@ func NewClient(host, user, pass string, opts ...Option) *Client {
supermicro: supermicro.Config{
Port: "443",
},
rpc: rpc.Provider{},
},
}

Expand Down Expand Up @@ -129,7 +134,29 @@ func (c *Client) defaultTimeout(ctx context.Context) time.Duration {
return time.Until(deadline) / time.Duration(l)
}

func (c *Client) registerRPCProvider() error {
driverRPC := rpc.New(c.providerConfig.rpc.ConsumerURL, c.Auth.Host, c.providerConfig.rpc.Opts.HMAC.Secrets)
c.providerConfig.rpc.Logger = c.Logger
if err := mergo.Merge(driverRPC, c.providerConfig.rpc, mergo.WithOverride, mergo.WithTransformers(&rpc.Provider{})); err != nil {
return fmt.Errorf("failed to merge user specified rpc config with the config defaults, rpc provider not available: %w", err)
}
c.Registry.Register(rpc.ProviderName, rpc.ProviderProtocol, rpc.Features, nil, driverRPC)

return nil
}

func (c *Client) registerProviders() {
// register the rpc provider
joelrebel marked this conversation as resolved.
Show resolved Hide resolved
// without the consumer URL there is no way to send RPC requests.
if c.providerConfig.rpc.ConsumerURL != "" {
// when the rpc provider is to be used, we won't register any other providers.
err := c.registerRPCProvider()
if err == nil {
c.Logger.Info("note: with the rpc provider registered, no other providers will be registered and available")
return
}
c.Logger.Info("failed to register rpc provider, falling back to registering all other providers", "error", err.Error())
}
// register ipmitool provider
ipmiOpts := []ipmitool.Option{
ipmitool.WithLogger(c.Logger),
Expand Down
3 changes: 1 addition & 2 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ func TestBMC(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
cl := NewClient(host, user, pass, WithLogger(log), WithPerProviderTimeout(5*time.Second))
err := cl.Open(ctx)
if err != nil {
if err := cl.Open(ctx); err != nil {
t.Logf("%+v", cl.GetMetadata())
t.Fatal(err)
}
Expand Down
94 changes: 94 additions & 0 deletions examples/rpc/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"context"
"encoding/json"
"net/http"
"time"

"github.com/bmc-toolbox/bmclib/v2"
"github.com/bmc-toolbox/bmclib/v2/logging"
"github.com/bmc-toolbox/bmclib/v2/providers/rpc"
)

func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Start the test consumer
go testConsumer(ctx)
time.Sleep(100 * time.Millisecond)

log := logging.ZeroLogger("info")
opts := []bmclib.Option{
bmclib.WithLogger(log),
bmclib.WithPerProviderTimeout(5 * time.Second),
bmclib.WithRPCOpt(rpc.Provider{
ConsumerURL: "http://localhost:8800",
// Opts are not required.
Opts: rpc.Opts{
HMAC: rpc.HMACOpts{
Secrets: rpc.Secrets{rpc.SHA256: {"superSecret1"}},
},
Signature: rpc.SignatureOpts{
HeaderName: "X-Bespoke-Signature",
IncludedPayloadHeaders: []string{"X-Bespoke-Timestamp"},
},
Request: rpc.RequestOpts{
TimestampHeader: "X-Bespoke-Timestamp",
},
},
}),
}
host := "127.0.1.1"
user := "admin"
pass := "admin"
c := bmclib.NewClient(host, user, pass, opts...)
if err := c.Open(ctx); err != nil {
panic(err)
}
defer c.Close(ctx)

state, err := c.GetPowerState(ctx)
if err != nil {
panic(err)
}
log.Info("power state", "state", state)
log.Info("metadata for GetPowerState", "metadata", c.GetMetadata())

ok, err := c.SetPowerState(ctx, "on")
if err != nil {
panic(err)
}
log.Info("set power state", "ok", ok)
log.Info("metadata for SetPowerState", "metadata", c.GetMetadata())

<-ctx.Done()
}

func testConsumer(ctx context.Context) error {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
req := rpc.RequestPayload{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
rp := rpc.ResponsePayload{
ID: req.ID,
Host: req.Host,
}
switch req.Method {
case rpc.PowerGetMethod:
rp.Result = "on"
case rpc.PowerSetMethod:

case rpc.BootDeviceMethod:

default:
w.WriteHeader(http.StatusNotFound)
}
b, _ := json.Marshal(rp)
w.Write(b)
})

return http.ListenAndServe(":8800", nil)
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ module github.com/bmc-toolbox/bmclib/v2
go 1.18

require (
dario.cat/mergo v1.0.0
github.com/Jeffail/gabs/v2 v2.7.0
github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d
github.com/bombsimon/logrusr/v2 v2.0.1
github.com/ghodss/yaml v1.0.0
github.com/go-logr/logr v1.2.4
github.com/go-logr/zerologr v1.2.3
github.com/google/go-cmp v0.5.9
github.com/hashicorp/go-multierror v1.1.1
github.com/jacobweinstock/iamt v0.0.0-20230502042727-d7cdbe67d9ef
github.com/jacobweinstock/registrar v0.4.7
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.30.0
github.com/sirupsen/logrus v1.8.1
github.com/stmcginnis/gofish v0.14.0
github.com/stretchr/testify v1.8.0
Expand All @@ -26,8 +31,11 @@ require (
github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
golang.org/x/sys v0.1.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
20 changes: 20 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Jeffail/gabs/v2 v2.7.0 h1:Y2edYaTcE8ZpRsR2AtmPu5xQdFDIthFG0jYhu5PY8kg=
github.com/Jeffail/gabs/v2 v2.7.0/go.mod h1:dp5ocw1FvBBQYssgHsG7I1WYsiLRtkUaB1FEtSwvNUw=
github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230 h1:t95Grn2mOPfb3+kPDWsNnj4dlNcxnvuR72IjY8eYjfQ=
github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230/go.mod h1:t2EzW1qybnPDQ3LR/GgeF0GOzHUXT5IVMLP2gkW1cmc=
github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 h1:a0MBqYm44o0NcthLKCljZHe1mxlN6oahCQHHThnSwB4=
Expand All @@ -6,13 +10,19 @@ github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d h1:cQ30Wa8mhLzK
github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c=
github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM=
github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/zerologr v1.2.3 h1:up5N9vcH9Xck3jJkXzgyOxozT14R47IyDODz8LM1KSs=
github.com/go-logr/zerologr v1.2.3/go.mod h1:BxwGo7y5zgSHYR1BjbnHPyF/5ZjVKfKxAZANVu6E8Ho=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand All @@ -31,10 +41,17 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
Expand All @@ -59,6 +76,8 @@ golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
Expand All @@ -67,6 +86,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
2 changes: 1 addition & 1 deletion lint.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ LINTERS :=
FIXERS :=

GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml
GOLANGCI_LINT_VERSION ?= v1.51.2
GOLANGCI_LINT_VERSION ?= v1.53.3
GOLANGCI_LINT_BIN := $(LINT_ROOT)/out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH)
$(GOLANGCI_LINT_BIN):
mkdir -p $(LINT_ROOT)/out/linters
Expand Down
19 changes: 19 additions & 0 deletions logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

"github.com/bombsimon/logrusr/v2"
"github.com/go-logr/logr"
"github.com/go-logr/zerologr"
"github.com/rs/zerolog"
"github.com/sirupsen/logrus"
)

Expand All @@ -26,3 +28,20 @@ func DefaultLogger() logr.Logger {

return logrusr.New(logrusLog)
}

// ZeroLogger is a logr.Logger implementation that uses zerolog.
// This logger handles nested structs better than the logrus implementation.
func ZeroLogger(level string) logr.Logger {
zl := zerolog.New(os.Stdout)
zl = zl.With().Caller().Timestamp().Logger()
var l zerolog.Level
switch level {
case "debug":
l = zerolog.DebugLevel
default:
l = zerolog.InfoLevel
}
zl = zl.Level(l)

return zerologr.New(&zl)
}
7 changes: 7 additions & 0 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/bmc-toolbox/bmclib/v2/internal/httpclient"
"github.com/bmc-toolbox/bmclib/v2/providers/rpc"
"github.com/go-logr/logr"
"github.com/jacobweinstock/registrar"
)
Expand Down Expand Up @@ -137,3 +138,9 @@ func WithDellRedfishUseBasicAuth(useBasicAuth bool) Option {
args.providerConfig.dell.UseBasicAuth = useBasicAuth
}
}

func WithRPCOpt(opt rpc.Provider) Option {
return func(args *Client) {
args.providerConfig.rpc = opt
}
}
12 changes: 12 additions & 0 deletions providers/rpc/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Package rpc is a provider that defines an HTTP request/response contract for handling BMC interactions.
It allows users a simple way to interoperate with an existing/bespoke out-of-band management solution.

The rpc provider request/response payloads are modeled after JSON-RPC 2.0, but are not JSON-RPC 2.0
joelrebel marked this conversation as resolved.
Show resolved Hide resolved
compliant so as to allow for more flexibility and interoperability with existing systems.

The rpc provider has options that can be set to include an HMAC signature in the request header.
It follows the features found at https://webhooks.fyi/security/hmac, this includes hash algorithms sha256
and sha512, replay prevention, versioning, and key rotation.
*/
package rpc
26 changes: 26 additions & 0 deletions providers/rpc/experimental.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package rpc

import (
"github.com/Jeffail/gabs/v2"
"github.com/ghodss/yaml"
)

// embedPayload will embed the RequestPayload into the given JSON object at the dot path notation location ("object.data").
func (p *RequestPayload) embedPayload(rawJSON []byte, dotPath string) ([]byte, error) {
if rawJSON == nil {
return rawJSON, nil
}
jdata2, err := yaml.YAMLToJSON(rawJSON)
if err != nil {
return nil, err
}
g, err := gabs.ParseJSON(jdata2)
if err != nil {
return nil, err
}
if _, err := g.SetP(p, dotPath); err != nil {
return nil, err
}

return g.Bytes(), nil
}
Loading