PowerShell / PowerShell/DSC

Define semantic exit codes for the PowerShell adapters

Đang mở
#421 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Issue-Enhancement Needs Triage
Ngôn ngữ chính
Rust
Star
526
Fork
76
Merge trung bình
3 ngày 16 giờ
Pull request đã merge (30 ngày)
24

Mô tả

Summary of the new feature / enhancement

As a user and integrating vendor, I want to be able to quickly map the exit code from the PowerShell and Windows PowerShell adapters to their semantics, so I can understand what went wrong at a high-level before I investigate the error specifically.

Currently, the Microsoft.DSC/PowerShell and Microsoft.Windows/WindowsPowerShell adapters only define exit codes 0 (success) and 1 (error).

Proposed technical implementation details (optional)

Define reusable semantic exit codes for the adapter in psDscAdapter.psm1 and use them in the adapter code.

For example,

enum DscAdapterExitCode {
    Success = 0
    Failure
    InvocationError
    ImportPsdscModuleError
    ScriptBasedResourcesWindowsOnly
    BinaryResourceWindowsPowerShellOnly
    BinaryResourceUnsupported
    ImplementationDetailUnsupported
    ResourceNotFound
    InputJsonErrorCreatingConfigurationObject
    InputJsonErrorListingDscResourceTypes
    DscResourceModuleNotFound
    IncompleteGetResult
}

<# public function Write-JsonMessage
.SYNOPSIS
    This function writes a JSON formatted trace message to the host stderr.
.DESCRIPTION
    This function is designed to write a JSON formatted trace message to the host stderr. The trace
    message is intended to be used for debugging purposes and can be parsed by other tools, like
    DSC itself.
.PARAMETER Message
    The message to be written to the host stderr. This message will be written as a JSON object
    with the key being the value of the Level parameter.
.PARAMETER Level
    The level of the trace message. The default value is 'Debug'. The valid values are 'Trace',
    'Debug', 'Info', 'Warning', and 'Error'. These levels map to the levels that DSC uses for
    trace messages.
#>
function Write-JsonMessage {
    [CmdletBinding(HelpUri = '')]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Message,

        [Parameter(Position = 1)]
        [ValidateSet('Trace', 'Debug', 'Info', 'Warning', 'Error')]
        [string]$Level = 'Debug'
    )

    $json = @{ $Level = $Message } | ConvertTo-Json -Compress

    $host.ui.WriteErrorLine($json)
}

class DscAdapterError {
    [int]    $ExitCode
    [string] $ErrorMessage

    WriteAndExit() {
        Write-JsonMessage -Level Error -Message $this.ErrorMessage
        exit $this.ExitCode
    }

    static [DscAdapterError] ImportPsdscModuleError([string]$importModuleError) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::ImportPsdscModuleError
            ErrorMessage = "Could not import PSDesiredStateConfiguration 1.1 in Windows PowerShell. $importModuleError"
        }
    }

    static [DscAdapterError] ScriptBasedResourcesWindowsOnly([DscResourceInfo]$resource) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::ScriptBasedResourcesWindowsOnly
            ErrorMessage = "Resource $resource is script-based. Script-based resources are only supported on Windows."
        }
    }

    static [DscAdapterError] InvocationError([string]$operation, [DscResourceInfo]$resource, [string]$errorMessage) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::InvocationError
            ErrorMessage = "Error invoking '$operation' on ${resource}: $errorMessage"
        }
    }

    static [DscAdapterError] BinaryResourceWindowsPowerShellOnly([DscResourceInfo]$resource) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::BinaryResourceWindowsPowerShellOnly
            ErrorMessage = "Resource $resource is a binary resource. Only the File, Log, and SignatureValidation binary resources are supported. To use a supported binary resource, use the Microsoft.DSC/WindowsPowerShell adapter."
        }
    }

    static [DscAdapterError] BinaryResourceUnsupported([DscResourceInfo]$resource) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::BinaryResourceUnsupported
            ErrorMessage = "Resource $resource is not a supported binary resource. Only the File, Log, and SignatureValidation binary resources are supported."
        }
    }

    static [DscAdapterError] ImplementationDetailUnsupported([DscResourceInfo]$resource) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::ImplementationDetailUnsupported
            ErrorMessage = "Resource $resource has an unsupported implementation '$($resource.ImplementationDetail)'. Supported implementations are: $([dscResourceType].GetEnumNames())"
        }
    }

    static [DscAdapterError] ResourceNotFound([string]$type, [string]$json) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::ResourceNotFound
            ErrorMessage = "Can not find type '$type' for resource '$json'. Please ensure that Get-DscResource returns this resource type."
        }
    }

    static [DscAdapterError] InputJsonErrorCreatingConfigurationObject([string]$jsonInput) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::InputJsonError
            ErrorMessage = "Failed to create configuration object from provided input JSON: $jsonInput"
        }
    }

    static [DscAdapterError] InputJsonErrorListingDscResourceTypes() {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::InputJsonError
            ErrorMessage = "Could not get list of DSC resource types from provided JSON."
        }
    }

    static [DscAdapterError] DscResourceModuleNotFound() {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::DscResourceModuleNotFound
            ErrorMessage = "DSC resource module not found."
        }
    }

    static [DscAdapterError] IncompleteGetResult([string]$resourceType) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::IncompleteGetResult
            ErrorMessage = "Incomplete GET for resource $resourceType"
        }
    }

    static [DscAdapterError] UnknownError([string]$errorMessage) {
        return [DscAdapterError]@{
            ExitCode     = [DscAdapterExitCode]::Failure
            ErrorMessage = $errorMessage
        }
    }
}

Then, when you need to use a specific exit code:

# in psDscAdapter.psm1

# For Linux/MacOS, only class based resources are supported and are called directly.
if ($IsLinux) {
    [DscAdapterError]::ScriptBasedResourcesWindowsOnly($cachedDscResourceInfo).WriteAndExit()
}
# in  powershell.resource.ps1

# load private functions of psDscAdapter stub module
$psDscAdapter = Import-Module "$PSScriptRoot/psDscAdapter.psd1" -Force -PassThru
# get handle to adapter errors for semantic exit codes/messages
$psDscAdapterError = $psDscAdapter.Invoke({ [DscAdapterError] })

# ...

$psDscAdapterError::IncompleteGetForResource($ds.Name).WriteAndExit()

Then we could map the exit codes to their semantic meanings and reuse errors as needed. This proposal also includes the helper function Write-JsonMessage for sending a JSON Line back to DSC for debug, warnings, errors, etc.

While out of scope for now, we should also consider whether and how to do i18n for exit codes and error messages. In this proposal I'm just matching the use of en-US already in place for the module and adapter.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách theo dõi cách xử lý mã thoát hiện tại trong psDscAdapter.psm1 và powershell.resource.ps1, bao gồm cách hai adapter PowerShell tải và gọi mã adapter dùng chung. Được xem là hoàn thành khi các mã thoát ngữ nghĩa có thể tái sử dụng và việc xử lý lỗi được định nghĩa ở đó, đồng thời được sử dụng nhất quán cho các trường hợp adapter thất bại được liệt kê.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
powershell
Lĩnh vực
cli
Loại issue
Tính năng
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.