commit ce291e1a983ab475fc9e7257ee9e465ccf9c0f69 Author: Jacob Payne Date: Mon Mar 20 09:28:45 2023 -0700 init commit diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..d948f86 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,22 @@ +name: CI +on: + push: + branches: + - main + pull_request: true +env: + FORCE_COLOR: 1 +jobs: + setup: + runs-on: ubuntu-latest + steps: + - uses: earthly/actions-setup@v1 + with: + version: v0.7.* + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: lint + run: earthly --ci +lint + - name: unittest + run: earthly --ci +test \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..fed6eab --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,21 @@ +name: Release +on: + push: + tags: + - v* +env: + FORCE_COLOR: 1 +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: earthly/actions-setup@v1 + with: + version: v0.7.* + - name: docker login + run: docker login --username $FOO --password $FOO + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: lint + run: earthly --ci --push +image \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8264d98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +artifacts/ \ No newline at end of file diff --git a/Earthfile b/Earthfile new file mode 100644 index 0000000..be6c2dc --- /dev/null +++ b/Earthfile @@ -0,0 +1,83 @@ +VERSION 0.7 + +ARG --global GOLANG_VERSION=1.19.7 +ARG --global AMTRPC_VERSION=v2.6.0 +ARG --global GOLINT_VERSION=v1.51.2 +ARG --global IMAGE_REPOSITORY=quay.io/kairos-io/provider-amt + +builder: + FROM golang:$GOLANG_VERSION + + RUN apt update \ + && apt install -y upx git \ + && wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin $GOLINT_VERSION + + WORKDIR /build + + COPY go.mod go.sum ./ + + RUN go mod download + +version: + FROM +builder + + COPY .git .git + + RUN --no-cache echo $(git describe --always --tags --dirty) > VERSION + + ARG VERSION=$(cat VERSION) + SAVE ARTIFACT VERSION VERSION + +amt-rpc-lib: + FROM +builder + + GIT CLONE --branch $AMTRPC_VERSION git@github.com:open-amt-cloud-toolkit/rpc-go.git . + + RUN go build -buildmode=c-shared -o librpc.so ./cmd + + SAVE ARTIFACT librpc.so + SAVE ARTIFACT librpc.h + +build: + FROM +builder + + ENV CGO_ENABLED=1 + + COPY cmd cmd + COPY pkg pkg + + COPY +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so + COPY +amt-rpc-lib/librpc.h /usr/local/include/librpc.h + + RUN go build -o provider-amt cmd/main.go && upx provider-amt + + SAVE ARTIFACT provider-amt AS LOCAL artifacts/provider-amt + +image: + FROM +version + + ARG VERSION=$(cat VERSION) + + FROM scratch + + COPY +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so + COPY +amt-rpc-lib/librpc.h /usr/local/include/librpc.h + COPY +build/provider-amt /system/providers/provider-amt + + SAVE IMAGE --push $IMAGE_REPOSITORY:$VERSION + +test: + FROM +builder + + COPY cmd cmd + COPY pkg pkg + + RUN go test -v -tags fake ./... + +lint: + FROM +builder + + COPY cmd cmd + COPY pkg pkg + + RUN golangci-lint run \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..b4d6f71 --- /dev/null +++ b/Readme.md @@ -0,0 +1,20 @@ +Provider AMT +--- + +Provider AMT adds support for configuring Intel Active Management Tools during Kairos installation. + +```yaml +#cloud-config +amt: + dns_suffix_override: "" # Hostname override + hostname: "" # Hostname override + lms_address: "" # LMS address (default "localhost"). Can be used to change location of LMS for debugging. + lms_port: "" # LMS port (default "16992") + proxy_address: "" # Proxy address and port + password: "" # AMT password + profile: ""# Name of the profile to use + server_address: "" # WebSocket address of server to activate against + timeout: "" # timeout for activation + extra: # extra arguments to pass to the activate command + -foo: bar +``` \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..3c86a0b --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,144 @@ +package main + +import ( + "encoding/json" + "fmt" + "github.com/kairos-io/kairos-sdk/bus" + "github.com/mudler/go-pluggable" + "github.com/sirupsen/logrus" + "os" + "provider-amt/pkg/amtrpc" + "reflect" + "rpc/pkg/utils" + "strings" +) + +const ( + StateActive = "active" + StateError = "error" + StateUnavailable = "unavailable" + StateSkipped = "skipped" +) + +type AMT struct { + DnsSuffixOverride string `json:"dns_suffix_override,omitempty" flag:"-d"` + Hostname string `json:"hostname,omitempty" flag:"-h"` + LMSAddress string `json:"lms_address,omitempty" flag:"-lmsaddress"` + LMSPort string `json:"lms_port,omitempty" flag:"-lmsport"` + ProxyAddress string `json:"proxy_address,omitempty" flag:"-p"` + Password string `json:"password,omitempty" flag:"-password"` + Profile string `json:"profile,omitempty" flag:"-profile"` + ServerAddress string `json:"server_address,omitempty" flag:"-u"` + Timeout string `json:"timeout,omitempty" flag:"-t"` + Extra map[string]string `json:"extra,omitempty"` +} + +type Configuration struct { + AMT *AMT `yaml:"amt,omitempty" json:"amt,omitempty"` +} + +func main() { + err := pluggable.NewPluginFactory( + 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 { + logrus.Fatal(err) + } +} + +func getConfiguration(event *pluggable.Event) (*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 == utils.AmtNotDetected { + return pluggable.EventResponse{ + State: StateUnavailable, + Data: event.Data, + Logs: "no intel AMT device detected", + } + } + + return pluggable.EventResponse{ + 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 { + return pluggable.EventResponse{ + State: StateError, + Data: event.Data, + Error: fmt.Sprintf("failed to activate AMT device with status code: %d", status), + Logs: response, + } + } + + return pluggable.EventResponse{ + State: StateActive, + Data: event.Data, + } +} + +const flagTag = "flag" + +func toCLIFlags(command string, config any, extra map[string]string) string { + t := reflect.TypeOf(config).Elem() + val := reflect.ValueOf(config).Elem() + for i := 0; i < t.NumField(); i++ { + flag := t.Field(i).Tag.Get(flagTag) + fval := val.Field(i).String() + + if flag == "" || val.Field(i).IsZero() { + continue + } + + command = strings.Join([]string{command, flag, fval}, " ") + } + + if extra != nil { + for k, v := range extra { + command = strings.Join([]string{command, k, v}, " ") + } + } + + return command +} diff --git a/cmd/main_test.go b/cmd/main_test.go new file mode 100644 index 0000000..93ce767 --- /dev/null +++ b/cmd/main_test.go @@ -0,0 +1,149 @@ +package main + +import ( + "encoding/json" + "github.com/kairos-io/kairos-sdk/bus" + "github.com/mudler/go-pluggable" + "github.com/stretchr/testify/assert" + "provider-amt/pkg/amtrpc" + "rpc/pkg/utils" + "testing" +) + +var amtUnavailable = amtrpc.AMTRPC{ + MockAccessStatus: func() int { return utils.AmtNotDetected }, + MockExec: func(s string) (string, int) { return "", utils.Success }, +} + +var amtAccessError = amtrpc.AMTRPC{ + MockAccessStatus: func() int { return utils.IncorrectPermissions }, + MockExec: func(s string) (string, int) { return "", utils.Success }, +} + +var amtActive = amtrpc.AMTRPC{ + MockAccessStatus: func() int { return utils.Success }, + MockExec: func(s string) (string, int) { return "", utils.Success }, +} + +var amtExecError = amtrpc.AMTRPC{ + MockAccessStatus: func() int { return utils.Success }, + MockExec: func(s string) (string, int) { return "", utils.ActivationFailed }, +} + +func Test_activateAMTUnavailable(t *testing.T) { + config := Configuration{ + AMT: &AMT{ + ServerAddress: "wss://fake", + }, + } + event := encodeConfiguration(config) + + resp := activateAMT(amtUnavailable, event) + + assert.Equal(t, StateUnavailable, resp.State) + assert.Equal(t, event.Data, resp.Data) +} + +func Test_activateAMTCheckAccessError(t *testing.T) { + config := Configuration{ + AMT: &AMT{ + ServerAddress: "wss://fake", + }, + } + event := encodeConfiguration(config) + + resp := activateAMT(amtAccessError, event) + + assert.Equal(t, StateError, resp.State) + assert.Equal(t, event.Data, resp.Data) +} + +func Test_activateAMTNoConfiguration(t *testing.T) { + config := Configuration{} + event := encodeConfiguration(config) + + resp := activateAMT(amtActive, event) + + 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) { + config := Configuration{ + AMT: &AMT{ + ServerAddress: "wss://fake", + }, + } + event := encodeConfiguration(config) + + resp := activateAMT(amtExecError, event) + + assert.Equal(t, StateError, resp.State) + assert.Equal(t, event.Data, resp.Data) +} + +func Test_activateAMTStandard(t *testing.T) { + var execCommand string + + config := Configuration{ + AMT: &AMT{ + ServerAddress: "wss://fake", + Extra: map[string]string{ + "-foo": "bar", + }, + }, + } + event := encodeConfiguration(config) + amt := amtrpc.AMTRPC{ + MockAccessStatus: func() int { return utils.Success }, + MockExec: func(s string) (string, int) { + execCommand = s + return "", utils.Success + }, + } + + resp := activateAMT(amt, event) + + assert.Contains(t, execCommand, "activate") + assert.Contains(t, execCommand, "-u "+config.AMT.ServerAddress) + assert.Contains(t, execCommand, "-foo bar") + assert.Equal(t, StateActive, resp.State) + 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), + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e7f06b5 --- /dev/null +++ b/go.mod @@ -0,0 +1,23 @@ +module provider-amt + +go 1.19 + +require ( + github.com/kairos-io/kairos-sdk v0.0.1 + github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.2 + gopkg.in/yaml.v2 v2.4.0 + rpc v0.0.0-00010101000000-000000000000 +) + +require ( + github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/sys v0.6.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace rpc => github.com/open-amt-cloud-toolkit/rpc-go v0.0.0-20230306150617-96cc235bf732 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a2d9d71 --- /dev/null +++ b/go.sum @@ -0,0 +1,95 @@ +github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4= +github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs= +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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/kairos-io/kairos-sdk v0.0.1 h1:obJw0/5amn+/wWNuDTVq81HcPuX5TwHbGS4xxEy9Ju4= +github.com/kairos-io/kairos-sdk v0.0.1/go.mod h1:E70cYgGQpu1MXI8ddhH4CHVIvNi3w7l6MQlxLTeBTXY= +github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mVt7lh9glAryzQblMsbJYU2VnrdZ8yHlTs= +github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/open-amt-cloud-toolkit/rpc-go v0.0.0-20230306150617-96cc235bf732 h1:Cs7rjyWPHrrk7AObU7h8k3q+T0tfivn22oFXuDxHbrs= +github.com/open-amt-cloud-toolkit/rpc-go v0.0.0-20230306150617-96cc235bf732/go.mod h1:+SZ/fNjyeGaUlUPW70HBUtrNK8f0h1l0gs4eGH2XKQY= +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/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/amtrpc/amtrpc.go b/pkg/amtrpc/amtrpc.go new file mode 100644 index 0000000..e9ec47b --- /dev/null +++ b/pkg/amtrpc/amtrpc.go @@ -0,0 +1,29 @@ +//go:build !fake + +package amtrpc + +/* +#cgo CFLAGS: -I./src +#cgo LDFLAGS: -L./lib -lrpc -Wl,-rpath=./lib +#include +#include "librpc.h" +*/ +import "C" //nolint:typecheck +import "unsafe" + +type AMTRPC struct{} + +func (A AMTRPC) CheckAccess() int { + return int(C.rpcCheckAccess()) +} + +func (A AMTRPC) Exec(command string) (string, int) { + ccmd := C.CString(command) + cresponse := C.CString("") + cstatus := C.rpcExec(ccmd, &cresponse) + + C.free(unsafe.Pointer(ccmd)) + C.free(unsafe.Pointer(cresponse)) + + return C.GoString(cresponse), int(cstatus) +} diff --git a/pkg/amtrpc/fake.go b/pkg/amtrpc/fake.go new file mode 100644 index 0000000..e8ae0de --- /dev/null +++ b/pkg/amtrpc/fake.go @@ -0,0 +1,16 @@ +//go:build fake + +package amtrpc + +type AMTRPC struct { + MockAccessStatus func() int + MockExec func(string) (string, int) +} + +func (f AMTRPC) CheckAccess() int { + return f.MockAccessStatus() +} + +func (f AMTRPC) Exec(command string) (string, int) { + return f.MockExec(command) +} diff --git a/pkg/amtrpc/interface.go b/pkg/amtrpc/interface.go new file mode 100644 index 0000000..8289609 --- /dev/null +++ b/pkg/amtrpc/interface.go @@ -0,0 +1,6 @@ +package amtrpc + +type Interface interface { + CheckAccess() int + Exec(command string) (string, int) +} diff --git a/pkg/amtrpc/lib/librpc.h b/pkg/amtrpc/lib/librpc.h new file mode 100644 index 0000000..914dc03 --- /dev/null +++ b/pkg/amtrpc/lib/librpc.h @@ -0,0 +1,82 @@ +/* Code generated by cmd/cgo; DO NOT EDIT. */ + +/* package rpc/cmd */ + + +#line 1 "cgo-builtin-export-prolog" + +#include + +#ifndef GO_CGO_EXPORT_PROLOGUE_H +#define GO_CGO_EXPORT_PROLOGUE_H + +#ifndef GO_CGO_GOSTRING_TYPEDEF +typedef struct { const char *p; ptrdiff_t n; } _GoString_; +#endif + +#endif + +/* Start of preamble from import "C" comments. */ + + + + +/* End of preamble from import "C" comments. */ + + +/* Start of boilerplate cgo prologue. */ +#line 1 "cgo-gcc-export-header-prolog" + +#ifndef GO_CGO_PROLOGUE_H +#define GO_CGO_PROLOGUE_H + +typedef signed char GoInt8; +typedef unsigned char GoUint8; +typedef short GoInt16; +typedef unsigned short GoUint16; +typedef int GoInt32; +typedef unsigned int GoUint32; +typedef long long GoInt64; +typedef unsigned long long GoUint64; +typedef GoInt64 GoInt; +typedef GoUint64 GoUint; +typedef size_t GoUintptr; +typedef float GoFloat32; +typedef double GoFloat64; +#ifdef _MSC_VER +#include +typedef _Fcomplex GoComplex64; +typedef _Dcomplex GoComplex128; +#else +typedef float _Complex GoComplex64; +typedef double _Complex GoComplex128; +#endif + +/* + static assertion to make sure the file is being used on architecture + at least with matching size of GoInt. +*/ +typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; + +#ifndef GO_CGO_GOSTRING_TYPEDEF +typedef _GoString_ GoString; +#endif +typedef void *GoMap; +typedef void *GoChan; +typedef struct { void *t; void *v; } GoInterface; +typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; + +#endif + +/* End of boilerplate cgo prologue. */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern GoInt rpcCheckAccess(); +extern GoInt rpcExec(char* Input, char** Output); + +#ifdef __cplusplus +} +#endif diff --git a/pkg/amtrpc/src/librpc.so b/pkg/amtrpc/src/librpc.so new file mode 100644 index 0000000..6e6abf2 Binary files /dev/null and b/pkg/amtrpc/src/librpc.so differ