Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions internal/commands/configure/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type ConfigureCmd struct {
MEBx MEBxCmd `cmd:"" name:"mebx" aliases:"setmebx" help:"Configure MEBx password"`
AMTPassword AMTPasswordCmd `cmd:"" aliases:"amtpassword,changeamtpassword" help:"Change AMT password"`
AMTFeatures AMTFeaturesCmd `cmd:"" aliases:"amtfeatures,setamtfeatures" help:"Configure AMT features (KVM, SOL, IDER, user consent)"`
EnableAMT EnableAMTCmd `cmd:"" aliases:"enableamt" help:"Enable AMT operational state (requires unprovisioned state)"`
DisableAMT DisableAMTCmd `cmd:"" aliases:"disableamt" help:"Disable AMT operational state (requires unprovisioned state)"`
CIRA CIRACmd `cmd:"cira" help:"Configure Cloud-Initiated Remote Access (CIRA)"`
SyncClock SyncClockCmd `cmd:"" aliases:"syncclock,synctime" help:"Synchronize host OS clock to AMT"`
WiFiSync WifiSyncCmd `cmd:"" aliases:"wifisync,wifi" help:"Control WiFi and local profile synchronization"`
Expand Down
70 changes: 70 additions & 0 deletions internal/commands/configure/disableamt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2024
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

package configure

import (
"fmt"

"github.com/device-management-toolkit/rpc-go/v2/internal/commands"
"github.com/device-management-toolkit/rpc-go/v2/pkg/utils"
log "github.com/sirupsen/logrus"
)

// DisableAMTCmd represents the disable AMT command
type DisableAMTCmd struct {
ConfigureBaseCmd
}

// Validate implements Kong's Validate interface for DisableAMT command validation
func (cmd *DisableAMTCmd) Validate() error {
return cmd.ConfigureBaseCmd.Validate()
}

// Run executes the disable AMT command
func (cmd *DisableAMTCmd) Run(ctx *commands.Context) error {
log.Info("Disabling AMT...")

// Check if AMT can be disabled
changeEnabled, err := ctx.AMTCommand.GetChangeEnabled()
if err != nil {
log.Error("Failed to get change enabled status: ", err)
return utils.AMTConnectionFailed
}

// Log diagnostic information
log.Debugf("ChangeEnabled response: 0x%02X", uint8(changeEnabled))
log.Debugf("IsNewInterfaceVersion: %t", changeEnabled.IsNewInterfaceVersion())
log.Debugf("IsTransitionAllowed: %t", changeEnabled.IsTransitionAllowed())
log.Debugf("IsAMTEnabled: %t", changeEnabled.IsAMTEnabled())

// Check if this AMT version supports SetAmtOperationalState
if !changeEnabled.IsNewInterfaceVersion() {
log.Warnf("This AMT version may not support SetAmtOperationalState command (response: 0x%02X)", uint8(changeEnabled))
log.Info("Attempting to disable AMT anyway...")
}

// Check if AMT is already disabled
if !changeEnabled.IsAMTEnabled() {
log.Info("AMT is already disabled")
return nil
}

// Warn about transition state but attempt anyway
if !changeEnabled.IsTransitionAllowed() {
log.Warnf("AMT transition may not be allowed in current state (response: 0x%02X)", uint8(changeEnabled))
log.Info("This typically means the device is not in unprovisioned state")
log.Info("Attempting to disable AMT anyway...")
}

// Disable AMT
if err := ctx.AMTCommand.DisableAMT(); err != nil {
log.Error("Failed to disable AMT: ", err)
return fmt.Errorf("failed to disable AMT: %w", err)
}

log.Info("AMT disabled successfully")
return nil
}

Check failure on line 70 in internal/commands/configure/disableamt.go

View workflow job for this annotation

GitHub Actions / runner / golangci-lint

[golangci] reported by reviewdog 🐶 File is not properly formatted (gci) Raw Output: internal/commands/configure/disableamt.go:70:1: File is not properly formatted (gci) } ^
118 changes: 118 additions & 0 deletions internal/commands/configure/disableamt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2024
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

package configure

import (
"errors"
"testing"

"github.com/device-management-toolkit/rpc-go/v2/internal/commands"
mock "github.com/device-management-toolkit/rpc-go/v2/internal/mocks"
"github.com/device-management-toolkit/rpc-go/v2/pkg/amt"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)

func TestDisableAMTCmd_Run_Success(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x83), nil) // 10000011 in binary
mockAMT.EXPECT().DisableAMT().Return(nil)

cmd := &DisableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.NoError(t, err)
}

func TestDisableAMTCmd_Run_AlreadyDisabled(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x81), nil) // 10000001 in binary

cmd := &DisableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.NoError(t, err)
}

func TestDisableAMTCmd_Run_OldInterfaceVersion(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x03), nil) // 00000011 in binary

cmd := &DisableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "AMT version does not support enable/disable operations")
}

func TestDisableAMTCmd_Run_TransitionNotAllowed(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x82), nil) // 10000010 in binary

cmd := &DisableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "AMT operational state change not allowed")
}

func TestDisableAMTCmd_Run_DisableAMTError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x83), nil) // 10000011 in binary
mockAMT.EXPECT().DisableAMT().Return(errors.New("disable failed"))

cmd := &DisableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to disable AMT")
}

func TestDisableAMTCmd_Run_GetChangeEnabledError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0), errors.New("connection failed"))

cmd := &DisableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
}

Check failure on line 118 in internal/commands/configure/disableamt_test.go

View workflow job for this annotation

GitHub Actions / runner / golangci-lint

[golangci] reported by reviewdog 🐶 File is not properly formatted (gci) Raw Output: internal/commands/configure/disableamt_test.go:118:1: File is not properly formatted (gci) } ^
70 changes: 70 additions & 0 deletions internal/commands/configure/enableamt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2024
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

package configure

import (
"fmt"

"github.com/device-management-toolkit/rpc-go/v2/internal/commands"
"github.com/device-management-toolkit/rpc-go/v2/pkg/utils"
log "github.com/sirupsen/logrus"
)

// EnableAMTCmd represents the enable AMT command
type EnableAMTCmd struct {
ConfigureBaseCmd
}

// Validate implements Kong's Validate interface for EnableAMT command validation
func (cmd *EnableAMTCmd) Validate() error {
return cmd.ConfigureBaseCmd.Validate()
}

// Run executes the enable AMT command
func (cmd *EnableAMTCmd) Run(ctx *commands.Context) error {
log.Info("Enabling AMT...")

// Check if AMT can be enabled
changeEnabled, err := ctx.AMTCommand.GetChangeEnabled()
if err != nil {
log.Error("Failed to get change enabled status: ", err)
return utils.AMTConnectionFailed
}

// Log diagnostic information
log.Debugf("ChangeEnabled response: 0x%02X", uint8(changeEnabled))
log.Debugf("IsNewInterfaceVersion: %t", changeEnabled.IsNewInterfaceVersion())
log.Debugf("IsTransitionAllowed: %t", changeEnabled.IsTransitionAllowed())
log.Debugf("IsAMTEnabled: %t", changeEnabled.IsAMTEnabled())

// Check if this AMT version supports SetAmtOperationalState
if !changeEnabled.IsNewInterfaceVersion() {
log.Warnf("This AMT version may not support SetAmtOperationalState command (response: 0x%02X)", uint8(changeEnabled))
log.Info("Attempting to enable AMT anyway...")
}

// Check if AMT is already enabled
if changeEnabled.IsAMTEnabled() {
log.Info("AMT is already enabled")
return nil
}

// Warn about transition state but attempt anyway
if !changeEnabled.IsTransitionAllowed() {
log.Warnf("AMT transition may not be allowed in current state (response: 0x%02X)", uint8(changeEnabled))
log.Info("This typically means the device is not in unprovisioned state")
log.Info("Attempting to enable AMT anyway...")
}

// Enable AMT
if err := ctx.AMTCommand.EnableAMT(); err != nil {
log.Error("Failed to enable AMT: ", err)
return fmt.Errorf("failed to enable AMT: %w", err)
}

log.Info("AMT enabled successfully")
return nil
}

Check failure on line 70 in internal/commands/configure/enableamt.go

View workflow job for this annotation

GitHub Actions / runner / golangci-lint

[golangci] reported by reviewdog 🐶 File is not properly formatted (gci) Raw Output: internal/commands/configure/enableamt.go:70:1: File is not properly formatted (gci) } ^
118 changes: 118 additions & 0 deletions internal/commands/configure/enableamt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2024
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

package configure

import (
"errors"
"testing"

"github.com/device-management-toolkit/rpc-go/v2/internal/commands"
mock "github.com/device-management-toolkit/rpc-go/v2/internal/mocks"
"github.com/device-management-toolkit/rpc-go/v2/pkg/amt"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)

func TestEnableAMTCmd_Run_Success(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x81), nil) // 10000001 in binary
mockAMT.EXPECT().EnableAMT().Return(nil)

cmd := &EnableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.NoError(t, err)
}

func TestEnableAMTCmd_Run_AlreadyEnabled(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x83), nil) // 10000011 in binary

cmd := &EnableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.NoError(t, err)
}

func TestEnableAMTCmd_Run_OldInterfaceVersion(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x01), nil) // 00000001 in binary

cmd := &EnableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "AMT version does not support enable/disable operations")
}

func TestEnableAMTCmd_Run_TransitionNotAllowed(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x80), nil) // 10000000 in binary

cmd := &EnableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "AMT operational state change not allowed")
}

func TestEnableAMTCmd_Run_EnableAMTError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0x81), nil) // 10000001 in binary
mockAMT.EXPECT().EnableAMT().Return(errors.New("enable failed"))

cmd := &EnableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to enable AMT")
}

func TestEnableAMTCmd_Run_GetChangeEnabledError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockAMT := mock.NewMockInterface(ctrl)
mockAMT.EXPECT().GetChangeEnabled().Return(amt.ChangeEnabledResponse(0), errors.New("connection failed"))

cmd := &EnableAMTCmd{}
ctx := &commands.Context{
AMTCommand: mockAMT,
}

err := cmd.Run(ctx)
assert.Error(t, err)
}
Loading
Loading