Skip to content

Commit

Permalink
feat(amt): add execute support for setup (#104)
Browse files Browse the repository at this point in the history
Co-authored-by: Mike <[email protected]>
  • Loading branch information
zaidusmani26 and rsdmike authored Oct 30, 2023
1 parent 60dab36 commit fa7300c
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 57 deletions.
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

0 comments on commit fa7300c

Please sign in to comment.