converted from provider plugin to bundle binary

Signed-off-by: Jacob Payne <jacob@spectrocloud.com>
This commit is contained in:
Jacob Payne 2023-04-14 13:44:54 -07:00
parent fdedf683ee
commit 605659ba0e
4 changed files with 51 additions and 175 deletions

View File

@ -49,9 +49,10 @@ build:
COPY +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so COPY +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so
COPY +amt-rpc-lib/librpc.h /usr/local/include/librpc.h COPY +amt-rpc-lib/librpc.h /usr/local/include/librpc.h
RUN go build -ldflags "-linkmode 'external'" -o agent-provider-amt cmd/main.go && upx agent-provider-amt RUN go build -o agent-provider-amt cmd/main.go && upx agent-provider-amt
SAVE ARTIFACT agent-provider-amt AS LOCAL artifacts/agent-provider-amt SAVE ARTIFACT agent-provider-amt AS LOCAL artifacts/agent-provider-amt
SAVE ARTIFACT /usr/local/lib/librpc.so AS LOCAL artifacts/librpc.so
image: image:
FROM +version FROM +version
@ -60,9 +61,8 @@ image:
FROM scratch FROM scratch
COPY --chmod 0777 +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so COPY --chmod 0777 +amt-rpc-lib/librpc.so librpc.so
COPY --chmod 0777 +amt-rpc-lib/librpc.h /usr/local/include/librpc.h COPY --chmod 0777 +build/agent-provider-amt agent-provider-amt
COPY --chmod 0777 +build/agent-provider-amt /system/providers/agent-provider-amt
SAVE IMAGE --push $IMAGE_REPOSITORY:$VERSION SAVE IMAGE --push $IMAGE_REPOSITORY:$VERSION

View File

@ -1,11 +1,10 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"github.com/kairos-io/kairos-sdk/bus"
"github.com/mudler/go-pluggable"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
"io"
"os" "os"
"provider-amt/pkg/amtrpc" "provider-amt/pkg/amtrpc"
"reflect" "reflect"
@ -13,109 +12,46 @@ import (
"strings" "strings"
) )
const (
StateActive = "active"
StateError = "error"
StateUnavailable = "unavailable"
StateSkipped = "skipped"
)
type AMT struct { type AMT struct {
DnsSuffixOverride string `json:"dns_suffix_override,omitempty" flag:"-d"` DnsSuffixOverride string `json:"dns_suffix_override,omitempty" yaml:"dns_suffix_override,omitempty" flag:"-d"`
Hostname string `json:"hostname,omitempty" flag:"-h"` Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty" flag:"-h"`
LMSAddress string `json:"lms_address,omitempty" flag:"-lmsaddress"` LMSAddress string `json:"lms_address,omitempty" yaml:"lms_address,omitempty" flag:"-lmsaddress"`
LMSPort string `json:"lms_port,omitempty" flag:"-lmsport"` LMSPort string `json:"lms_port,omitempty" yaml:"lms_port,omitempty" flag:"-lmsport"`
ProxyAddress string `json:"proxy_address,omitempty" flag:"-p"` ProxyAddress string `json:"proxy_address,omitempty" yaml:"proxy_address,omitempty" flag:"-p"`
Password string `json:"password,omitempty" flag:"-password"` Password string `json:"password,omitempty" yaml:"password,omitempty" flag:"-password"`
Profile string `json:"profile,omitempty" flag:"-profile"` Profile string `json:"profile,omitempty" yaml:"profile,omitempty" flag:"-profile"`
ServerAddress string `json:"server_address,omitempty" flag:"-u"` ServerAddress string `json:"server_address,omitempty" yaml:"server_address,omitempty" flag:"-u"`
Timeout string `json:"timeout,omitempty" flag:"-t"` Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty" flag:"-t"`
Extra map[string]string `json:"extra,omitempty"` Extra map[string]string `json:"extra,omitempty" yaml:"extra,omitempty"`
}
type Configuration struct {
AMT *AMT `yaml:"amt,omitempty" json:"amt,omitempty"`
} }
func main() { func main() {
err := pluggable.NewPluginFactory( var config AMT
pluggable.FactoryPlugin{
EventType: bus.EventInstall,
PluginHandler: func(event *pluggable.Event) pluggable.EventResponse {
return activateAMT(amtrpc.AMTRPC{}, event)
},
},
).Run(pluggable.EventType(os.Args[1]), os.Stdin, os.Stdout)
if err != nil { if err := yaml.NewDecoder(io.TeeReader(os.Stdin, os.Stderr)).Decode(&config); err != nil {
logrus.Fatal(err) logrus.Fatal("failed to parse configuration: ", err)
}
if err := activateAMT(amtrpc.AMTRPC{}, &config); err != nil {
logrus.Fatal()
} }
} }
func getConfiguration(event *pluggable.Event) (*AMT, error) { func activateAMT(rpc amtrpc.Interface, config *AMT) error {
var payload bus.EventPayload
var config Configuration
// parse the event to get the configuration
if err := json.Unmarshal([]byte(event.Data), &payload); err != nil {
return nil, fmt.Errorf("failed to parse event payload %s", err.Error())
}
// parse the configuration to get the amt configuration
if err := json.Unmarshal([]byte(payload.Config), &config); err != nil {
return nil, fmt.Errorf("failed to parse configuration %s", err.Error())
}
return config.AMT, nil
}
func activateAMT(rpc amtrpc.Interface, event *pluggable.Event) pluggable.EventResponse {
config, err := getConfiguration(event)
if err != nil {
return pluggable.EventResponse{
State: StateError,
Data: event.Data,
Error: err.Error(),
}
}
// if no amt configuration is given we do nothing
if config == nil {
return pluggable.EventResponse{
State: StateSkipped,
Data: event.Data,
}
}
if status := rpc.CheckAccess(); status != utils.Success { if status := rpc.CheckAccess(); status != utils.Success {
if status == utils.AmtNotDetected { if status == utils.AmtNotDetected {
return pluggable.EventResponse{ logrus.Info("amt device could not be detected, skipping configuration")
State: StateUnavailable, return nil
Data: event.Data,
Logs: "no intel AMT device detected",
}
} }
return pluggable.EventResponse{ return fmt.Errorf("failed to access AMT device with status code: %d", status)
State: StateError,
Data: event.Data,
Error: fmt.Sprintf("failed to access AMT device with status code: %d", status),
}
} }
if response, status := rpc.Exec(toCLIFlags("activate", config, config.Extra)); status != utils.Success { if response, status := rpc.Exec(toCLIFlags("activate", config, config.Extra)); status != utils.Success {
return pluggable.EventResponse{ return fmt.Errorf("failed to access AMT device with status code: %d %s", status, response)
State: StateError,
Data: event.Data,
Error: fmt.Sprintf("failed to activate AMT device with status code: %d", status),
Logs: response,
}
} }
return pluggable.EventResponse{ return nil
State: StateActive,
Data: event.Data,
}
} }
const flagTag = "flag" const flagTag = "flag"

View File

@ -1,9 +1,6 @@
package main package main
import ( import (
"encoding/json"
"github.com/kairos-io/kairos-sdk/bus"
"github.com/mudler/go-pluggable"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"provider-amt/pkg/amtrpc" "provider-amt/pkg/amtrpc"
"rpc/pkg/utils" "rpc/pkg/utils"
@ -31,93 +28,50 @@ var amtExecError = amtrpc.AMTRPC{
} }
func Test_activateAMTUnavailable(t *testing.T) { func Test_activateAMTUnavailable(t *testing.T) {
config := Configuration{ config := &AMT{
AMT: &AMT{ ServerAddress: "wss://fake",
ServerAddress: "wss://fake",
},
} }
event := encodeConfiguration(config)
resp := activateAMT(amtUnavailable, event) err := activateAMT(amtUnavailable, config)
assert.Equal(t, StateUnavailable, resp.State) assert.NoError(t, err)
assert.Equal(t, event.Data, resp.Data)
} }
func Test_activateAMTCheckAccessError(t *testing.T) { func Test_activateAMTCheckAccessError(t *testing.T) {
config := Configuration{ config := &AMT{
AMT: &AMT{ ServerAddress: "wss://fake",
ServerAddress: "wss://fake",
},
} }
event := encodeConfiguration(config)
resp := activateAMT(amtAccessError, event) err := activateAMT(amtAccessError, config)
assert.Equal(t, StateError, resp.State) assert.Error(t, err)
assert.Equal(t, event.Data, resp.Data)
} }
func Test_activateAMTNoConfiguration(t *testing.T) { func Test_activateAMTNoConfiguration(t *testing.T) {
config := Configuration{} err := activateAMT(amtActive, &AMT{})
event := encodeConfiguration(config)
resp := activateAMT(amtActive, event) assert.NoError(t, err)
assert.Equal(t, StateSkipped, resp.State)
assert.Equal(t, event.Data, resp.Data)
}
func Test_activateAMTInvalidEventData(t *testing.T) {
config := Configuration{
AMT: &AMT{
ServerAddress: "wss://fake",
},
}
event := encodeConfiguration(config)
event.Data = event.Data[1:]
resp := activateAMT(amtActive, event)
assert.Equal(t, StateError, resp.State)
assert.Equal(t, event.Data, resp.Data)
}
func Test_activateAMTInvalidConfiguration(t *testing.T) {
event := &pluggable.Event{Data: `{"config":"{"}`}
resp := activateAMT(amtActive, event)
assert.Equal(t, StateError, resp.State)
assert.Equal(t, event.Data, resp.Data)
} }
func Test_activateAMTApplyError(t *testing.T) { func Test_activateAMTApplyError(t *testing.T) {
config := Configuration{ config := &AMT{
AMT: &AMT{ ServerAddress: "wss://fake",
ServerAddress: "wss://fake",
},
} }
event := encodeConfiguration(config)
resp := activateAMT(amtExecError, event) err := activateAMT(amtExecError, config)
assert.Equal(t, StateError, resp.State) assert.Error(t, err)
assert.Equal(t, event.Data, resp.Data)
} }
func Test_activateAMTStandard(t *testing.T) { func Test_activateAMTStandard(t *testing.T) {
var execCommand string var execCommand string
config := Configuration{ config := &AMT{
AMT: &AMT{ ServerAddress: "wss://fake",
ServerAddress: "wss://fake", Extra: map[string]string{
Extra: map[string]string{ "-foo": "bar",
"-foo": "bar",
},
}, },
} }
event := encodeConfiguration(config)
amt := amtrpc.AMTRPC{ amt := amtrpc.AMTRPC{
MockAccessStatus: func() int { return utils.Success }, MockAccessStatus: func() int { return utils.Success },
MockExec: func(s string) (string, int) { MockExec: func(s string) (string, int) {
@ -126,24 +80,10 @@ func Test_activateAMTStandard(t *testing.T) {
}, },
} }
resp := activateAMT(amt, event) err := activateAMT(amt, config)
assert.Contains(t, execCommand, "activate") assert.Contains(t, execCommand, "activate")
assert.Contains(t, execCommand, "-u "+config.AMT.ServerAddress) assert.Contains(t, execCommand, "-u "+config.ServerAddress)
assert.Contains(t, execCommand, "-foo bar") assert.Contains(t, execCommand, "-foo bar")
assert.Equal(t, StateActive, resp.State) assert.NoError(t, err)
assert.Equal(t, event.Data, resp.Data)
assert.False(t, resp.Errored())
}
func encodeConfiguration(config Configuration) *pluggable.Event {
inner, _ := json.Marshal(config)
data, _ := json.Marshal(bus.EventPayload{
Config: string(inner),
})
return &pluggable.Event{
Name: bus.EventInstall,
Data: string(data),
}
} }

View File

@ -3,7 +3,7 @@
package amtrpc package amtrpc
/* /*
#cgo LDFLAGS: -L/usr/local/lib -lrpc -Wl,-rpath=/usr/local/lib #cgo LDFLAGS: -L'$ORIGIN' -lrpc -Wl,-rpath='$ORIGIN'
#include <stdlib.h> #include <stdlib.h>
#include "librpc.h" #include "librpc.h"
*/ */