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

feat(amt): add execute support for setup #104

Merged
merged 8 commits into from
Oct 30, 2023
Merged
159 changes: 121 additions & 38 deletions pkg/amt/setupandconfiguration/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,46 @@
package setupandconfiguration

import (
"encoding/json"
"encoding/xml"
"fmt"

"github.com/open-amt-cloud-toolkit/go-wsman-messages/internal/message"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/amt/actions"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/cim/models"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/common"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/wsman"
)

const AMT_SetupAndConfigurationService = "AMT_SetupAndConfigurationService"

type (
Response struct {
*wsman.Message
XMLName xml.Name `xml:"Envelope"`
Header message.Header `xml:"Header"`
Body Body `xml:"Body"`
}
Body struct {
XMLName xml.Name `xml:"Body"`
Setup Setup `xml:"AMT_SetupAndConfigurationService"`

EnumerateResponse common.EnumerateResponse
}

Setup struct {
CreationClassName string
ElementName string
EnabledState int
Name string
PasswordModel int
ProvisioningMode int
ProvisioningServerOTP string
ProvisioningState int
RequestedState int
SystemCreationClassName string
SystemName string
ZeroTouchConfigurationEnabled bool
}
)
type UnprovisionResponse struct {
XMLName xml.Name `xml:"Envelope"`
Header message.Header `xml:"Header"`
Expand Down Expand Up @@ -48,56 +78,109 @@ type SetupAndConfigurationService struct {
ZeroTouchConfigurationEnabled string
}
}

func (w *Response) JSON() string {
jsonOutput, err := json.Marshal(w.Body)
if err != nil {
return ""
}
return string(jsonOutput)
}

type Service struct {
base message.Base
base message.Base
client wsman.WSManClient
}

func NewSetupAndConfigurationService(wsmanMessageCreator *message.WSManMessageCreator) Service {
return Service{
base: message.NewBase(wsmanMessageCreator, AMT_SetupAndConfigurationService),
base: message.NewBase(wsmanMessageCreator, AMT_SetupAndConfigurationService),
client: nil,
}
}
func (s Service) Get() string {
return s.base.Get(nil)
}

// Enumerates the instances of this class
func (s Service) Enumerate() string {
return s.base.Enumerate()
func NewSetupAndConfigurationServiceWithClient(wsmanMessageCreator *message.WSManMessageCreator, client wsman.WSManClient) Service {
return Service{
base: message.NewBaseWithClient(wsmanMessageCreator, AMT_SetupAndConfigurationService, client),
client: client,
}
}
func (s Service) Get() (response Response, err error) {
response = Response{
Message: &wsman.Message{
XMLInput: s.base.Get(nil),
},
}

// Pulls instances of this class, following an Enumerate operation
func (s Service) Pull(enumerationContext string) string {
return s.base.Pull(enumerationContext)
}
// send the message to AMT
err = s.base.Execute(response.Message)
if err != nil {
return
}

// Put will change properties of the selected instance
func (s Service) Put(setupAndConfigurationService SetupAndConfigurationService) string {
return s.base.Put(setupAndConfigurationService, false, nil)
}
func (s Service) CommitChanges() string {
header := s.base.WSManMessageCreator.CreateHeader(string(actions.CommitChanges), AMT_SetupAndConfigurationService, nil, "", "")
body := s.base.WSManMessageCreator.CreateBody("CommitChanges_INPUT", AMT_SetupAndConfigurationService, nil)
return s.base.WSManMessageCreator.CreateXML(header, body)
}
// put the xml response into the go struct
err = xml.Unmarshal([]byte(response.XMLOutput), &response)
if err != nil {
return
}

func (s Service) GetUuid() string {
header := s.base.WSManMessageCreator.CreateHeader(string(actions.GetUuid), AMT_SetupAndConfigurationService, nil, "", "")
body := s.base.WSManMessageCreator.CreateBody("GetUuid_INPUT", AMT_SetupAndConfigurationService, nil)
return s.base.WSManMessageCreator.CreateXML(header, body)
return
}

func (s Service) SetMEBXPassword(password string) string {
header := s.base.WSManMessageCreator.CreateHeader(string(actions.SetMEBxPassword), AMT_SetupAndConfigurationService, nil, "", "")
body := fmt.Sprintf(`<Body><h:SetMEBxPassword_INPUT xmlns:h="%s%s"><h:Password>%s</h:Password></h:SetMEBxPassword_INPUT></Body>`, s.base.WSManMessageCreator.ResourceURIBase, AMT_SetupAndConfigurationService, password)
return s.base.WSManMessageCreator.CreateXML(header, body)
}
// Enumerates the instances of this class
func (s Service) Enumerate() (response Response, err error) {
response = Response{
Message: &wsman.Message{
XMLInput: s.base.Enumerate(),
},
}
// send the message to AMT
err = s.base.Execute(response.Message)
if err != nil {
return
}

func (s Service) Unprovision(provisioningMode int) string {
if provisioningMode == 0 {
provisioningMode = 1
// put the xml response into the go struct
err = xml.Unmarshal([]byte(response.XMLOutput), &response)
if err != nil {
return
}
header := s.base.WSManMessageCreator.CreateHeader(string(actions.Unprovision), AMT_SetupAndConfigurationService, nil, "", "")
body := fmt.Sprintf(`<Body><h:Unprovision_INPUT xmlns:h="%s%s"><h:ProvisioningMode>%d</h:ProvisioningMode></h:Unprovision_INPUT></Body>`, s.base.WSManMessageCreator.ResourceURIBase, AMT_SetupAndConfigurationService, provisioningMode)
return s.base.WSManMessageCreator.CreateXML(header, body)

return
}

// Pulls instances of this class, following an Enumerate operation
// func (s Service) Pull(enumerationContext string) string {
// return s.base.Pull(enumerationContext)
// }

// // Put will change properties of the selected instance
// func (s Service) Put(setupAndConfigurationService SetupAndConfigurationService) string {
// return s.base.Put(setupAndConfigurationService, false, nil)
// }
// func (s Service) CommitChanges() string {
// header := s.base.WSManMessageCreator.CreateHeader(string(actions.CommitChanges), AMT_SetupAndConfigurationService, nil, "", "")
// body := s.base.WSManMessageCreator.CreateBody("CommitChanges_INPUT", AMT_SetupAndConfigurationService, nil)
// return s.base.WSManMessageCreator.CreateXML(header, body)
// }

// func (s Service) GetUuid() string {
// header := s.base.WSManMessageCreator.CreateHeader(string(actions.GetUuid), AMT_SetupAndConfigurationService, nil, "", "")
// body := s.base.WSManMessageCreator.CreateBody("GetUuid_INPUT", AMT_SetupAndConfigurationService, nil)
// return s.base.WSManMessageCreator.CreateXML(header, body)
// }

// func (s Service) SetMEBXPassword(password string) string {
// header := s.base.WSManMessageCreator.CreateHeader(string(actions.SetMEBxPassword), AMT_SetupAndConfigurationService, nil, "", "")
// body := fmt.Sprintf(`<Body><h:SetMEBxPassword_INPUT xmlns:h="%s%s"><h:Password>%s</h:Password></h:SetMEBxPassword_INPUT></Body>`, s.base.WSManMessageCreator.ResourceURIBase, AMT_SetupAndConfigurationService, password)
// return s.base.WSManMessageCreator.CreateXML(header, body)
// }

// func (s Service) Unprovision(provisioningMode int) string {
// if provisioningMode == 0 {
// provisioningMode = 1
// }
// header := s.base.WSManMessageCreator.CreateHeader(string(actions.Unprovision), AMT_SetupAndConfigurationService, nil, "", "")
// body := fmt.Sprintf(`<Body><h:Unprovision_INPUT xmlns:h="%s%s"><h:ProvisioningMode>%d</h:ProvisioningMode></h:Unprovision_INPUT></Body>`, s.base.WSManMessageCreator.ResourceURIBase, AMT_SetupAndConfigurationService, provisioningMode)
// return s.base.WSManMessageCreator.CreateXML(header, body)
// }
115 changes: 96 additions & 19 deletions pkg/amt/setupandconfiguration/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,126 @@
package setupandconfiguration

import (
"encoding/xml"
"fmt"
"io"
"os"
"strings"
"testing"

"github.com/stretchr/testify/assert"

"github.com/open-amt-cloud-toolkit/go-wsman-messages/internal/message"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/amt/actions"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/common"
"github.com/open-amt-cloud-toolkit/go-wsman-messages/pkg/wsmantesting"
)

type MockClient struct {
}

const (
EnvelopeResponse = `<a:Envelope xmlns:a="http://www.w3.org/2003/05/soap-envelope" x-mlns:b="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:c="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:d="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:e="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:f="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:g="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_RedirectionService" xmlns:h="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><a:Header><b:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</b:To><b:RelatesTo>0</b:RelatesTo><b:Action a:mustUnderstand="true">`
GetBody = `<g:AMT_RedirectionService><g:CreationClassName>AMT_RedirectionService</g:CreationClassName><g:ElementName>Intel(r) AMT Redirection Service</g:ElementName><g:Name>Intel(r) AMT Redirection Service</g:Name><g:SystemCreationClassName>CIM_ComputerSystem</g:SystemCreationClassName><g:SystemName>ManagedSystem</g:SystemName></g:AMT_RedirectionService`
)

var currentMessage = ""

func (c *MockClient) Post(msg string) ([]byte, error) {
// read an xml file from disk:
xmlFile, err := os.Open("../../wsmantesting/responses/amt/setupandconfiguration/" + strings.ToLower(currentMessage) + ".xml")
if err != nil {
fmt.Println("Error opening file:", err)
return nil, err
}
defer xmlFile.Close()
// read file into string
xmlData, err := io.ReadAll(xmlFile)
if err != nil {
fmt.Println("Error reading file:", err)
return nil, err
}
// strip carriage returns and new line characters
xmlData = []byte(strings.ReplaceAll(string(xmlData), "\r\n", ""))

// Simulate a successful response for testing.
return []byte(xmlData), nil
}
func TestAMT_SetupAndConfigurationService(t *testing.T) {
messageID := 0
resourceUriBase := "http://intel.com/wbem/wscim/1/amt-schema/1/"
wsmanMessageCreator := message.NewWSManMessageCreator(resourceUriBase)
elementUnderTest := NewSetupAndConfigurationService(wsmanMessageCreator)
client := MockClient{}
elementUnderTest := NewSetupAndConfigurationServiceWithClient(wsmanMessageCreator, &client)

t.Run("amt_* Tests", func(t *testing.T) {
tests := []struct {
name string
method string
action string
body string
responseFunc func() string
name string
method string
action string
body string
responseFunc func() (Response, error)
expectedResponse interface{}
}{
//GETS
{"should create a valid AMT_SetupAndConfigurationService Get wsman message", "AMT_SetupAndConfigurationService", wsmantesting.GET, "", elementUnderTest.Get},
{
"should create a valid AMT_SetupAndConfigurationService Get wsman message",
"AMT_SetupAndConfigurationService",
wsmantesting.GET, "",
func() (Response, error) {
currentMessage = "Get"
return elementUnderTest.Get()
},
Body{
XMLName: xml.Name{Space: "http://www.w3.org/2003/05/soap-envelope", Local: "Body"},
Setup: Setup{
CreationClassName: "AMT_SetupAndConfigurationService",
ElementName: "Intel(r) AMT Setup and Configuration Service",
EnabledState: 5,
Name: "Intel(r) AMT Setup and Configuration Service",
PasswordModel: 1,
ProvisioningMode: 1,
ProvisioningServerOTP: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
ProvisioningState: 2,
RequestedState: 12,
SystemCreationClassName: "CIM_ComputerSystem",
SystemName: "Intel(r) AMT",
ZeroTouchConfigurationEnabled: true,
},
},
},
//ENUMERATES
{"should create a valid AMT_SetupAndConfigurationService Enumerate wsman message", "AMT_SetupAndConfigurationService", wsmantesting.ENUMERATE, wsmantesting.ENUMERATE_BODY, elementUnderTest.Enumerate},
{
"should create a valid AMT_SetupAndConfigurationService Enumerate wsman message",
"AMT_SetupAndConfigurationService",
wsmantesting.ENUMERATE,
wsmantesting.ENUMERATE_BODY,
func() (Response, error) {
currentMessage = "Enumerate"
return elementUnderTest.Enumerate()
},
Body{
XMLName: xml.Name{Space: "http://www.w3.org/2003/05/soap-envelope", Local: "Body"},
EnumerateResponse: common.EnumerateResponse{
EnumerationContext: "D3000000-0000-0000-0000-000000000000",
},
},
},
//PULLS
{"should create a valid AMT_SetupAndConfigurationService Pull wsman message", "AMT_SetupAndConfigurationService", wsmantesting.PULL, wsmantesting.PULL_BODY, func() string { return elementUnderTest.Pull(wsmantesting.EnumerationContext) }},
{"should create a valid AMT_SetupAndConfigurationService CommitChanges wsman message", "AMT_SetupAndConfigurationService", string(actions.CommitChanges), `<h:CommitChanges_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"></h:CommitChanges_INPUT>`, elementUnderTest.CommitChanges},
{"should create a valid AMT_SetupAndConfigurationService GetUuid wsman message", "AMT_SetupAndConfigurationService", string(actions.GetUuid), `<h:GetUuid_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"></h:GetUuid_INPUT>`, elementUnderTest.GetUuid},
{"should create a valid AMT_SetupAndConfigurationService SetMEBxPassword wsman message", "AMT_SetupAndConfigurationService", string(actions.SetMEBxPassword), `<h:SetMEBxPassword_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"><h:Password>P@ssw0rd</h:Password></h:SetMEBxPassword_INPUT>`, func() string { return elementUnderTest.SetMEBXPassword("P@ssw0rd") }},
{"should create a valid AMT_SetupAndConfigurationService Unprovision wsman message", "AMT_SetupAndConfigurationService", string(actions.Unprovision), `<h:Unprovision_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"><h:ProvisioningMode>1</h:ProvisioningMode></h:Unprovision_INPUT>`, func() string { return elementUnderTest.Unprovision(1) }},
// {"should create a valid AMT_SetupAndConfigurationService Pull wsman message", "AMT_SetupAndConfigurationService", wsmantesting.PULL, wsmantesting.PULL_BODY, func() string { return elementUnderTest.Pull(wsmantesting.EnumerationContext) }},
// {"should create a valid AMT_SetupAndConfigurationService CommitChanges wsman message", "AMT_SetupAndConfigurationService", string(actions.CommitChanges), `<h:CommitChanges_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"></h:CommitChanges_INPUT>`, elementUnderTest.CommitChanges},
// {"should create a valid AMT_SetupAndConfigurationService GetUuid wsman message", "AMT_SetupAndConfigurationService", string(actions.GetUuid), `<h:GetUuid_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"></h:GetUuid_INPUT>`, elementUnderTest.GetUuid},
// {"should create a valid AMT_SetupAndConfigurationService SetMEBxPassword wsman message", "AMT_SetupAndConfigurationService", string(actions.SetMEBxPassword), `<h:SetMEBxPassword_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"><h:Password>P@ssw0rd</h:Password></h:SetMEBxPassword_INPUT>`, func() string { return elementUnderTest.SetMEBXPassword("P@ssw0rd") }},
// {"should create a valid AMT_SetupAndConfigurationService Unprovision wsman message", "AMT_SetupAndConfigurationService", string(actions.Unprovision), `<h:Unprovision_INPUT xmlns:h="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService"><h:ProvisioningMode>1</h:ProvisioningMode></h:Unprovision_INPUT>`, func() string { return elementUnderTest.Unprovision(1) }},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
correctResponse := wsmantesting.ExpectedResponse(messageID, resourceUriBase, test.method, test.action, "", test.body)
expectedXMLInput := wsmantesting.ExpectedResponse(messageID, resourceUriBase, test.method, test.action, "", test.body)
messageID++
response := test.responseFunc()
if response != correctResponse {
assert.Equal(t, correctResponse, response)
}
response, err := test.responseFunc()
assert.NoError(t, err)
assert.Equal(t, expectedXMLInput, response.XMLInput)
assert.Equal(t, test.expectedResponse, response.Body)
})
}
})
Expand Down
22 changes: 22 additions & 0 deletions pkg/wsmantesting/responses/amt/setupandconfiguration/enumerate.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<a:Envelope xmlns:a="http://www.w3.org/2003/05/soap-envelope"
xmlns:b="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:c="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
xmlns:d="http://schemas.xmlsoap.org/ws/2005/02/trust"
xmlns:e="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:f="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd"
xmlns:g="http://schemas.xmlsoap.org/ws/2004/09/enumeration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<a:Header>
<b:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</b:To>
<b:RelatesTo>0</b:RelatesTo>
<b:Action a:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse</b:Action>
<b:MessageID>uuid:00000000-8086-8086-8086-000000000322</b:MessageID>
<c:ResourceURI>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_SetupAndConfigurationService</c:ResourceURI>
</a:Header>
<a:Body>
<g:EnumerateResponse>
<g:EnumerationContext>D3000000-0000-0000-0000-000000000000</g:EnumerationContext>
</g:EnumerateResponse>
</a:Body>
</a:Envelope>
Loading
Loading