Skip to content
Open
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: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ linters:
min-complexity: 16
goconst:
min-len: 2
min-occurrences: 3
min-occurrences: 5
gocritic:
disabled-checks:
- dupImport
Expand Down
11 changes: 8 additions & 3 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,14 @@ func PrintHelp(parser *kong.Kong, opts kong.HelpOptions, args []string) error {
}

// knownCommands lists the valid top-level command names for hasCommand detection.
const (
cmdAmtInfo = "amtinfo"
cmdVersion = "version"
)

var knownCommands = map[string]bool{
"amtinfo": true, "version": true, "activate": true,
"deactivate": true, "configure": true, "diagnostics": true, "diag": true,
cmdAmtInfo: true, cmdVersion: true, "activate": true,
"deactivate": true, "configure": true, "diagnostics": true, "diag": true, //nolint:goconst // command name literals; remaining occurrences are in tests
}

// hasCommand checks if args contain a recognized command name.
Expand Down Expand Up @@ -201,7 +206,7 @@ func Execute(args []string) error {
// but let --help/-h pass through so Kong shows the full command list.
if !hasCommand(args) && !hasFlag(args, "--help", "-h") {
newArgs := make([]string, 0, len(args)+1)
newArgs = append(newArgs, args[0], "amtinfo")
newArgs = append(newArgs, args[0], cmdAmtInfo)
newArgs = append(newArgs, args[1:]...)
args = newArgs
}
Expand Down
14 changes: 14 additions & 0 deletions internal/commands/activate/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2024
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

package activate

const (
keyStatus = "status"
keyMessage = "message"
keyFriendlyName = "friendly_name"
keyProfile = "profile"
valSuccess = "success"
)
18 changes: 9 additions & 9 deletions internal/commands/activate/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ func (cmd *LocalActivateCmd) handleStopConfiguration(ctx *commands.Context) erro

if ctx.JsonOutput {
result := map[string]interface{}{
"status": "success",
"message": "AMT configuration stopped",
keyStatus: valSuccess,
keyMessage: "AMT configuration stopped",
}

jsonBytes, err := json.MarshalIndent(result, "", " ")
Expand Down Expand Up @@ -390,10 +390,10 @@ func (service *LocalActivationService) activateCCM() error {
// Output success result
if service.context.JsonOutput {
result := map[string]interface{}{
"status": "success",
keyStatus: valSuccess,
"mode": "CCM",
"message": "Device activated in Client Control Mode",
"friendly_name": service.config.FriendlyName,
keyMessage: "Device activated in Client Control Mode",
keyFriendlyName: service.config.FriendlyName,
}

jsonBytes, err := json.MarshalIndent(result, "", " ")
Expand Down Expand Up @@ -477,10 +477,10 @@ func (service *LocalActivationService) activateACM() error {
// Output success result
if service.context.JsonOutput {
result := map[string]interface{}{
"status": "success",
keyStatus: valSuccess,
"mode": "ACM",
"message": "Device activated in Admin Control Mode",
"friendly_name": service.config.FriendlyName,
keyMessage: "Device activated in Admin Control Mode",
keyFriendlyName: service.config.FriendlyName,
}

jsonBytes, err := json.MarshalIndent(result, "", " ")
Expand Down Expand Up @@ -875,7 +875,7 @@ func (service *LocalActivationService) runStartHBCWithRetry(certsAndKeys CertsAn

for attempt := 1; attempt <= hbcMaxAttempts; attempt++ {
response, err = service.startSecureHostBasedConfiguration(certsAndKeys)
if err == nil && response.Status == "AMT_STATUS_SUCCESS" {
if err == nil && response.Status == "AMT_STATUS_SUCCESS" { //nolint:goconst // AMT response status; remaining occurrences are in tests
return response, nil
}

Expand Down
12 changes: 6 additions & 6 deletions internal/commands/activate/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (service *RemoteActivationService) prepareDeviceInfo() map[string]interface
log.Debug("Preparing device information...")

deviceInfo := map[string]interface{}{
"profile": service.config.Profile,
keyProfile: service.config.Profile,
}
// Add optional fields if provided
if service.config.DNS != "" {
Expand All @@ -156,7 +156,7 @@ func (service *RemoteActivationService) prepareDeviceInfo() map[string]interface
}

if service.config.FriendlyName != "" {
deviceInfo["friendly_name"] = service.config.FriendlyName
deviceInfo[keyFriendlyName] = service.config.FriendlyName
}

return deviceInfo
Expand Down Expand Up @@ -194,15 +194,15 @@ func (service *RemoteActivationService) requestActivation(deviceInfo map[string]
}
// Create success result for our Kong CLI pattern
result := map[string]interface{}{
"status": "success",
keyStatus: valSuccess,

"message": "Device activated successfully via RPS",
keyMessage: "Device activated successfully via RPS",

"rps_server": service.config.URL,

"profile": service.config.Profile,
keyProfile: service.config.Profile,

"friendly_name": service.config.FriendlyName,
keyFriendlyName: service.config.FriendlyName,

"device_info": deviceInfo,
}
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/amtinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func renderInfoRow(label, value string) string {

func styledInfoValue(value string) string {
switch strings.ToLower(strings.TrimSpace(value)) {
case "enabled", "connected", "up", "active",
case "enabled", "connected", "up", "active", //nolint:goconst // status string literals; remaining occurrences are in tests
"post-provisioning", "admin control mode":
return infoGreenStyle.Render(value)
case "disabled", "not connected", "down",
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/diagnostics/wsman.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ var wsmanClassFetchers = map[string]classFetcher{
"AMT_EnvironmentDetectionSettingData": fetchAMTEnvironmentDetectionSettingData,
"AMT_EventLogEntry": rawWSMANClassFetcher("AMT_EventLogEntry"),
"AMT_EthernetPortSettings": fetchAMTEthernetPortSettings,
"AMT_GeneralSettings": fetchAMTGeneralSettings,
"AMT_GeneralSettings": fetchAMTGeneralSettings, //nolint:goconst // WSMAN class name; remaining occurrences are in tests
"AMT_Hdr8021Filter": rawWSMANClassFetcher("AMT_Hdr8021Filter"),
"AMT_ManagementPresenceRemoteSAP": fetchAMTManagementPresenceRemoteSAP,
"AMT_MessageLog": fetchAMTMessageLog,
Expand Down
8 changes: 4 additions & 4 deletions internal/orchestrator/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ func (e *CLIExecutor) Execute(args []string) error {
// Get the current executable path
executable, err := os.Executable()
if err != nil {
// Fallback to "rpc" if we can't determine the executable
executable = "rpc"
// Fallback to cmdRPC if we can't determine the executable
executable = cmdRPC
}

// Replace the first "rpc" argument with the actual executable
if len(args) > 0 && args[0] == "rpc" {
// Replace the first cmdRPC argument with the actual executable
if len(args) > 0 && args[0] == cmdRPC {
args = args[1:]
}

Expand Down
9 changes: 5 additions & 4 deletions internal/orchestrator/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var ErrCIRAConfiguration = errors.New("CIRA configuration failed")

const (
ACMMODE = "acmactivate"
cmdRPC = "rpc"
)

// ProfileOrchestrator orchestrates the execution of commands from a profile configuration
Expand Down Expand Up @@ -59,7 +60,7 @@ func NewProfileOrchestrator(cfg config.Configuration, currentPassword, mebxPassw

// baseArgs returns the common CLI arguments including global flags like password and skip-amt-cert-check.
func (po *ProfileOrchestrator) baseArgs() []string {
args := []string{"rpc"}
args := []string{cmdRPC}
if po.skipAMTCertCheck {
args = append(args, "--skip-amt-cert-check")
}
Expand Down Expand Up @@ -203,7 +204,7 @@ func (po *ProfileOrchestrator) executeWithPasswordFallback(args []string) error

// If caller supplied a currentPassword, try non-interactive rotation once
if po.currentPassword != "" {
change := []string{"rpc", "configure", "amtpassword", "--password", po.currentPassword, "--newamtpassword", newPass}
change := []string{cmdRPC, "configure", "amtpassword", "--password", po.currentPassword, "--newamtpassword", newPass}
if po.skipAMTCertCheck {
change = append(change, "--skip-amt-cert-check")
}
Expand Down Expand Up @@ -243,7 +244,7 @@ func (po *ProfileOrchestrator) executeWithPasswordFallback(args []string) error
}

// Execute password change: configure amtpassword --password <old> --newamtpassword <new>
change := []string{"rpc", "configure", "amtpassword", "--password", oldPass, "--newamtpassword", newPass}
change := []string{cmdRPC, "configure", "amtpassword", "--password", oldPass, "--newamtpassword", newPass}
if po.skipAMTCertCheck {
change = append(change, "--skip-amt-cert-check")
}
Expand Down Expand Up @@ -691,7 +692,7 @@ func (po *ProfileOrchestrator) verifyAndAlignAMTPassword() error {

// If a current password was supplied by the caller, try a direct non-interactive rotation first
if po.currentPassword != "" {
change := []string{"rpc", "configure", "amtpassword", "--password", po.currentPassword, "--newamtpassword", newPass}
change := []string{cmdRPC, "configure", "amtpassword", "--password", po.currentPassword, "--newamtpassword", newPass}
if po.skipAMTCertCheck {
change = append(change, "--skip-amt-cert-check")
}
Expand Down
36 changes: 19 additions & 17 deletions pkg/utils/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package utils

type ReturnCode int

const msgActivationFailed = "ActivationFailed"

var (
ProjectVersion string = "Development Build"
BuildDate string = "unknown"
Expand Down Expand Up @@ -119,7 +121,7 @@ var (
var (
AMTAuthenticationFailed = CustomError{Code: 100, Message: "AMTAuthenticationFailed"}
WSMANMessageError = CustomError{Code: 101, Message: "WSMANMessageError"}
ActivationFailed = CustomError{Code: 102, Message: "ActivationFailed"}
ActivationFailed = CustomError{Code: 102, Message: msgActivationFailed}
NetworkConfigurationFailed = CustomError{Code: 103, Message: "NetworkConfigurationFailed"}
CIRAConfigurationFailed = CustomError{Code: 104, Message: "CIRAConfigurationFailed"}
TLSConfigurationFailed = CustomError{Code: 105, Message: "TLSConfigurationFailed"}
Expand All @@ -137,24 +139,24 @@ var (
SetMEBXPasswordFailed = CustomError{Code: 118, Message: "SetMEBXPasswordFailed"}
ChangeAMTPasswordFailed = CustomError{Code: 119, Message: "ChangeAMTPasswordFailed"}
UnableToConfigure = CustomError{Code: 120, Message: "UnableToConfigure"}
ActivationFailedDecode64 = CustomError{Code: 121, Message: "ActivationFailed", Details: "failed to decode the certificate from Base64 format"}
ActivationFailedWrongCertPass = CustomError{Code: 122, Message: "ActivationFailed", Details: "provisioning cert password incorrect"}
ActivationFailedInvalidProvCert = CustomError{Code: 123, Message: "ActivationFailed", Details: "invalid provisioning certificate"}
ActivationFailedNoCertFound = CustomError{Code: 124, Message: "ActivationFailed", Details: "no certificates found"}
ActivationFailedNoPrivKeys = CustomError{Code: 125, Message: "ActivationFailed", Details: "no private keys found"}
ActivationFailedNoRootCertFound = CustomError{Code: 126, Message: "ActivationFailed", Details: "root certificate not found in the pfx"}
ActivationFailedGetCertHash = CustomError{Code: 127, Message: "ActivationFailed", Details: "failed to get certificate hashes"}
ActivationFailedProvCertNoMatch = CustomError{Code: 128, Message: "ActivationFailed", Details: "the root of the provisioning certificate does not match any of the trusted roots in AMT"}
ActivationFailedGeneralSettings = CustomError{Code: 129, Message: "ActivationFailed", Details: "wsman message error, failed to get general settings"}
ActivationFailedSetupService = CustomError{Code: 130, Message: "ActivationFailed", Details: "wsman message error, failed to get host based setup service response"}
ActivationFailedAddCert = CustomError{Code: 131, Message: "ActivationFailed", Details: "wsman message error, failed to add certificate to AMT"}
ActivationFailedGenerateNonce = CustomError{Code: 132, Message: "ActivationFailed", Details: "failed to generate nonce"}
ActivationFailedSignString = CustomError{Code: 133, Message: "ActivationFailed", Details: "failed to create signed string"}
ActivationFailedGetControlMode = CustomError{Code: 134, Message: "ActivationFailed", Details: "failed to get control mode"}
ActivationFailedControlMode = CustomError{Code: 135, Message: "ActivationFailed", Details: "received invalid control mode"}
ActivationFailedDecode64 = CustomError{Code: 121, Message: msgActivationFailed, Details: "failed to decode the certificate from Base64 format"}
ActivationFailedWrongCertPass = CustomError{Code: 122, Message: msgActivationFailed, Details: "provisioning cert password incorrect"}
ActivationFailedInvalidProvCert = CustomError{Code: 123, Message: msgActivationFailed, Details: "invalid provisioning certificate"}
ActivationFailedNoCertFound = CustomError{Code: 124, Message: msgActivationFailed, Details: "no certificates found"}
ActivationFailedNoPrivKeys = CustomError{Code: 125, Message: msgActivationFailed, Details: "no private keys found"}
ActivationFailedNoRootCertFound = CustomError{Code: 126, Message: msgActivationFailed, Details: "root certificate not found in the pfx"}
ActivationFailedGetCertHash = CustomError{Code: 127, Message: msgActivationFailed, Details: "failed to get certificate hashes"}
ActivationFailedProvCertNoMatch = CustomError{Code: 128, Message: msgActivationFailed, Details: "the root of the provisioning certificate does not match any of the trusted roots in AMT"}
ActivationFailedGeneralSettings = CustomError{Code: 129, Message: msgActivationFailed, Details: "wsman message error, failed to get general settings"}
ActivationFailedSetupService = CustomError{Code: 130, Message: msgActivationFailed, Details: "wsman message error, failed to get host based setup service response"}
ActivationFailedAddCert = CustomError{Code: 131, Message: msgActivationFailed, Details: "wsman message error, failed to add certificate to AMT"}
ActivationFailedGenerateNonce = CustomError{Code: 132, Message: msgActivationFailed, Details: "failed to generate nonce"}
ActivationFailedSignString = CustomError{Code: 133, Message: msgActivationFailed, Details: "failed to create signed string"}
ActivationFailedGetControlMode = CustomError{Code: 134, Message: msgActivationFailed, Details: "failed to get control mode"}
ActivationFailedControlMode = CustomError{Code: 135, Message: msgActivationFailed, Details: "received invalid control mode"}
DuplicateKey = CustomError{Code: 136, Message: "DuplicateKey", Details: "Key pair already exists"}
WiredConfigurationFailed = CustomError{Code: 137, Message: "WiredConfigurationFailed"}
ActivationFailedCertHash = CustomError{Code: 138, Message: "ActivationFailed", Details: "leaf certificate hash too long"}
ActivationFailedCertHash = CustomError{Code: 138, Message: msgActivationFailed, Details: "leaf certificate hash too long"}
UnsupportedAMTVersion = CustomError{Code: 138, Message: "UnsupportedAMTVersion"}
LMSConnectionFailed = CustomError{Code: 139, Message: "LMSConnectionFailed", Details: "Failed to connect to LMS. Please install LMS for activation."}
)
Expand Down
Loading