diff --git a/CHANGELOG.md b/CHANGELOG.md index 8400b4394..65affc12d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,25 @@ No unreleased features * 22 => 422 (Unprocessable entity / invalid request) * 50 => 500 (Internal server error) +* Added `Remove-ApplicationBinary` command + + **Example: Remove all application binaries related to an application** + + **PowerShell** + + ```powershell + Remove-ApplicationBinary -Application 12345 -BinaryId 9876 + + # Or remove all application binaries (except the active one) for an application + Get-ApplicationBinaryCollection -Id 12345 | Remove-ApplicationBinary -Application 12345 + ``` + + **Bash/zsh** + + ```sh + c8y applications deleteApplicationBinary --application 12345 --binaryId 9876 + ``` + ### New Features (PSc8y) * Added support for saving meta information about the requests to the in-built PowerShell InformationVariable common parameter diff --git a/api/spec/json/applications.json b/api/spec/json/applications.json index 2ee429323..3df39d578 100644 --- a/api/spec/json/applications.json +++ b/api/spec/json/applications.json @@ -496,6 +496,69 @@ "description": "Application id" } ] + }, + { + "name": "deleteApplicationBinary", + "skip": false, + "description": "Remove application binary", + "descriptionLong": "Remove an application binaries related to the given application\nThe active version can not be deleted and the server will throw an error if you try.\n", + "method": "DELETE", + "path": "/application/applications/{application}/binaries/{binaryId}", + "alias": { + "go": "deleteApplicationBinary", + "powershell": "Remove-ApplicationBinary" + }, + "examples": { + "powershell": [ + { + "description": "Remove an application binary related to a Hosted (web) application", + "beforeEach": [ + "$app = New-TestHostedApplication", + "New-ApplicationBinary -Id $app -File", + "$appBinary = Get-ApplicationBinaryCollection -Id $App.id" + ], + "command": "Remove-ApplicationBinary -Application $app.id -BinaryId $appBinary.id", + "skipTest": true, + "afterEach": [ + "Remove-Application -Id $app.id" + ] + }, + { + "description": "Remove all application binaries (except for the active one) for an application (using pipeline)", + "beforeEach": [ + "$app = New-TestHostedApplication" + ], + "command": "Get-ApplicationBinaryCollection -Id $app.id | Remove-ApplicationBinary -Application $app.id", + "skipTest": true, + "afterEach": [ + "Remove-Application -Id $app.id" + ] + } + ], + "go": [ + { + "description": "Remove an application binary related to a Hosted (web) application", + "command": "c8y applications deleteApplicationBinary --application 12345 --binaryId 9876" + } + ] + }, + "pathParameters": [ + { + "name": "application", + "type": "application", + "pipeline": false, + "required": true, + "description": "Application id" + }, + { + "name": "binaryId", + "alias": "id", + "type": "[]string", + "pipeline": true, + "required": true, + "description": "Application binary id" + } + ] } ] } \ No newline at end of file diff --git a/api/spec/yaml/applications.yml b/api/spec/yaml/applications.yml index 789220a36..afafe5e18 100644 --- a/api/spec/yaml/applications.yml +++ b/api/spec/yaml/applications.yml @@ -365,3 +365,51 @@ endpoints: pipeline: true required: true description: Application id + + - name: deleteApplicationBinary + skip: false + description: 'Remove application binary' + descriptionLong: > + Remove an application binaries related to the given application + + The active version can not be deleted and the server will throw an error if you try. + method: DELETE + path: /application/applications/{application}/binaries/{binaryId} + alias: + go: deleteApplicationBinary + powershell: Remove-ApplicationBinary + examples: + powershell: + # TODO: Create a test function to update an application binary + - description: Remove an application binary related to a Hosted (web) application + beforeEach: + - $app = New-TestHostedApplication + - New-ApplicationBinary -Id $app -File + - $appBinary = Get-ApplicationBinaryCollection -Id $App.id + command: Remove-ApplicationBinary -Application $app.id -BinaryId $appBinary.id + skipTest: true + afterEach: + - Remove-Application -Id $app.id + - description: Remove all application binaries (except for the active one) for an application (using pipeline) + beforeEach: + - $app = New-TestHostedApplication + command: Get-ApplicationBinaryCollection -Id $app.id | Remove-ApplicationBinary -Application $app.id + skipTest: true + afterEach: + - Remove-Application -Id $app.id + go: + - description: Remove an application binary related to a Hosted (web) application + command: c8y applications deleteApplicationBinary --application 12345 --binaryId 9876 + pathParameters: + - name: application + type: application + pipeline: false + required: true + description: Application id + + - name: binaryId + alias: id + type: '[]string' + pipeline: true + required: true + description: Application binary id diff --git a/docs/_pwsh/cmdlets/New-Device.md b/docs/_pwsh/cmdlets/New-Device.md index 27f8fbc53..c2259a94a 100644 --- a/docs/_pwsh/cmdlets/New-Device.md +++ b/docs/_pwsh/cmdlets/New-Device.md @@ -17,7 +17,7 @@ Create a device ``` New-Device - [-Name] + [[-Name] ] [[-Type] ] [[-Data] ] [[-ProcessingMode] ] @@ -56,17 +56,17 @@ Create device with custom properties ## PARAMETERS ### -Name -Device name (required) +Device name ```yaml -Type: String[] +Type: String Parameter Sets: (All) Aliases: -Required: True +Required: False Position: 1 Default value: None -Accept pipeline input: True (ByPropertyName, ByValue) +Accept pipeline input: False Accept wildcard characters: False ``` diff --git a/docs/_pwsh/cmdlets/Remove-ApplicationBinary.md b/docs/_pwsh/cmdlets/Remove-ApplicationBinary.md new file mode 100644 index 000000000..24f4acf54 --- /dev/null +++ b/docs/_pwsh/cmdlets/Remove-ApplicationBinary.md @@ -0,0 +1,232 @@ +--- +category: Applications +external help file: PSc8y-help.xml +layout: powershell +Module Name: PSc8y +online version: +schema: 2.0.0 +title: Remove-ApplicationBinary +--- + +# Remove-ApplicationBinary + +## SYNOPSIS +Remove application binary + +## SYNTAX + +``` +Remove-ApplicationBinary + [-Application] + [-BinaryId] + [[-ProcessingMode] ] + [-Raw] + [[-OutputFile] ] + [-NoProxy] + [[-Session] ] + [[-TimeoutSec] ] + [-Force] + [-WhatIf] + [-Confirm] + [] +``` + +## DESCRIPTION +Remove an application binaries related to the given application +The active version can not be deleted and the server will throw an error if you try. + +## EXAMPLES + +### EXAMPLE 1 +``` +Remove-ApplicationBinary -Application $app.id -BinaryId $appBinary.id +``` + +Remove an application binary related to a Hosted (web) application + +### EXAMPLE 2 +``` +Get-ApplicationBinaryCollection -Id $app.id | Remove-ApplicationBinary -Application $app.id +``` + +Remove all application binaries (except for the active one) for an application (using pipeline) + +## PARAMETERS + +### -Application +Application id (required) + +```yaml +Type: Object[] +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -BinaryId +Application binary id (required) + +```yaml +Type: String[] +Parameter Sets: (All) +Aliases: id + +Required: True +Position: 2 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ProcessingMode +Cumulocity processing mode + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Raw +Show the full (raw) response from Cumulocity including pagination information + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -OutputFile +Write the response to file + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -NoProxy +Ignore any proxy settings when running the cmdlet + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Session +Specifiy alternative Cumulocity session to use when running the cmdlet + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 5 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -TimeoutSec +TimeoutSec timeout in seconds before a request will be aborted + +```yaml +Type: Double +Parameter Sets: (All) +Aliases: + +Required: False +Position: 6 +Default value: 0 +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Force +Don't prompt for confirmation + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +## OUTPUTS + +### System.Object +## NOTES + +## RELATED LINKS diff --git a/pkg/cmd/applicationsRootCmd.go b/pkg/cmd/applicationsRootCmd.go index fbb7a60ef..14ecb3d8d 100644 --- a/pkg/cmd/applicationsRootCmd.go +++ b/pkg/cmd/applicationsRootCmd.go @@ -26,6 +26,7 @@ func newApplicationsRootCmd() *applicationsCmd { cmd.AddCommand(newUpdateApplicationCmd().getCommand()) cmd.AddCommand(newNewApplicationBinaryCmd().getCommand()) cmd.AddCommand(newGetApplicationBinaryCollectionCmd().getCommand()) + cmd.AddCommand(newDeleteApplicationBinaryCmd().getCommand()) ccmd.baseCmd = newBaseCmd(cmd) diff --git a/pkg/cmd/deleteApplicationBinaryCmd.auto.go b/pkg/cmd/deleteApplicationBinaryCmd.auto.go new file mode 100644 index 000000000..f427e1911 --- /dev/null +++ b/pkg/cmd/deleteApplicationBinaryCmd.auto.go @@ -0,0 +1,126 @@ +// Code generated from specification version 1.0.0: DO NOT EDIT +package cmd + +import ( + "fmt" + "io" + "net/http" + "net/url" + + "github.com/reubenmiller/go-c8y-cli/pkg/mapbuilder" + "github.com/reubenmiller/go-c8y/pkg/c8y" + "github.com/spf13/cobra" +) + +type deleteApplicationBinaryCmd struct { + *baseCmd +} + +func newDeleteApplicationBinaryCmd() *deleteApplicationBinaryCmd { + ccmd := &deleteApplicationBinaryCmd{} + + cmd := &cobra.Command{ + Use: "deleteApplicationBinary", + Short: "Remove application binary", + Long: `Remove an application binaries related to the given application +The active version can not be deleted and the server will throw an error if you try. +`, + Example: ` +$ c8y applications deleteApplicationBinary --application 12345 --binaryId 9876 +Remove an application binary related to a Hosted (web) application + `, + PreRunE: validateDeleteMode, + RunE: ccmd.deleteApplicationBinary, + } + + cmd.SilenceUsage = true + + cmd.Flags().String("application", "", "Application id (required)") + cmd.Flags().StringSlice("binaryId", []string{""}, "Application binary id (required)") + addProcessingModeFlag(cmd) + + // Required flags + cmd.MarkFlagRequired("application") + cmd.MarkFlagRequired("binaryId") + + ccmd.baseCmd = newBaseCmd(cmd) + + return ccmd +} + +func (n *deleteApplicationBinaryCmd) deleteApplicationBinary(cmd *cobra.Command, args []string) error { + + commonOptions, err := getCommonOptions(cmd) + if err != nil { + return newUserError(fmt.Sprintf("Failed to get common options. err=%s", err)) + } + + // query parameters + queryValue := url.QueryEscape("") + query := url.Values{} + queryValue, err = url.QueryUnescape(query.Encode()) + + if err != nil { + return newSystemError("Invalid query parameter") + } + + // headers + headers := http.Header{} + if cmd.Flags().Changed("processingMode") { + if v, err := cmd.Flags().GetString("processingMode"); err == nil && v != "" { + headers.Add("X-Cumulocity-Processing-Mode", v) + } + } + + // form data + formData := make(map[string]io.Reader) + + // body + body := mapbuilder.NewMapBuilder() + + // path parameters + pathParameters := make(map[string]string) + if cmd.Flags().Changed("application") { + applicationInputValues, applicationValue, err := getApplicationSlice(cmd, args, "application") + + if err != nil { + return newUserError("no matching applications found", applicationInputValues, err) + } + + if len(applicationValue) == 0 { + return newUserError("no matching applications found", applicationInputValues) + } + + for _, item := range applicationValue { + if item != "" { + pathParameters["application"] = newIDValue(item).GetID() + } + } + } + if items, err := cmd.Flags().GetStringSlice("binaryId"); err == nil { + if len(items) > 0 { + for _, v := range items { + if v != "" { + pathParameters["binaryId"] = v + } + } + } + } else { + return newUserError("Flag does not exist") + } + + path := replacePathParameters("/application/applications/{application}/binaries/{binaryId}", pathParameters) + + req := c8y.RequestOptions{ + Method: "DELETE", + Path: path, + Query: queryValue, + Body: body.GetMap(), + FormData: formData, + Header: headers, + IgnoreAccept: false, + DryRun: globalFlagDryRun, + } + + return processRequestAndResponse([]c8y.RequestOptions{req}, commonOptions) +} diff --git a/scripts/build-powershell/New-C8yApiPowershellCommand.ps1 b/scripts/build-powershell/New-C8yApiPowershellCommand.ps1 index 43ca4091f..8fc87c6fa 100644 --- a/scripts/build-powershell/New-C8yApiPowershellCommand.ps1 +++ b/scripts/build-powershell/New-C8yApiPowershellCommand.ps1 @@ -221,9 +221,9 @@ $null = $CurrentParam.AppendLine(" # {0}" -f ($item.Description)) $null = $CurrentParam.AppendLine(" [Parameter({0})]" -f ($item.Definition -join ",`n ")) - # if ($iArg.alias) { - # $null = $CurrentParam.AppendLine(" [Alias(`"{0}`")]" -f $iArg.alias) - # } + if ($iArg.alias) { + $null = $CurrentParam.AppendLine(" [Alias(`"{0}`")]" -f $iArg.alias) + } # Validate set if ($null -ne $iArg.validationSet) { diff --git a/tools/PSc8y/PSc8y.psd1 b/tools/PSc8y/PSc8y.psd1 index b7524095d..f225e5109 100644 --- a/tools/PSc8y/PSc8y.psd1 +++ b/tools/PSc8y/PSc8y.psd1 @@ -204,6 +204,7 @@ FunctionsToExport = @( 'Remove-Agent', 'Remove-AlarmCollection', 'Remove-Application', + 'Remove-ApplicationBinary', 'Remove-AssetFromGroup', 'Remove-Binary', 'Remove-BulkOperation', diff --git a/tools/PSc8y/Public/Remove-ApplicationBinary.ps1 b/tools/PSc8y/Public/Remove-ApplicationBinary.ps1 new file mode 100644 index 000000000..b9fe3e3b7 --- /dev/null +++ b/tools/PSc8y/Public/Remove-ApplicationBinary.ps1 @@ -0,0 +1,137 @@ +# Code generated from specification version 1.0.0: DO NOT EDIT +Function Remove-ApplicationBinary { +<# +.SYNOPSIS +Remove application binary + +.DESCRIPTION +Remove an application binaries related to the given application +The active version can not be deleted and the server will throw an error if you try. + + +.EXAMPLE +PS> Remove-ApplicationBinary -Application $app.id -BinaryId $appBinary.id + +Remove an application binary related to a Hosted (web) application + +.EXAMPLE +PS> Get-ApplicationBinaryCollection -Id $app.id | Remove-ApplicationBinary -Application $app.id + +Remove all application binaries (except for the active one) for an application (using pipeline) + + +#> + [cmdletbinding(SupportsShouldProcess = $true, + PositionalBinding=$true, + HelpUri='', + ConfirmImpact = 'High')] + [Alias()] + [OutputType([object])] + Param( + # Application id (required) + [Parameter(Mandatory = $true)] + [object[]] + $Application, + + # Application binary id (required) + [Parameter(Mandatory = $true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true)] + [Alias("id")] + [string[]] + $BinaryId, + + # Cumulocity processing mode + [Parameter()] + [AllowNull()] + [AllowEmptyString()] + [ValidateSet("PERSISTENT", "QUIESCENT", "TRANSIENT", "CEP", "")] + [string] + $ProcessingMode, + + # Show the full (raw) response from Cumulocity including pagination information + [Parameter()] + [switch] + $Raw, + + # Write the response to file + [Parameter()] + [string] + $OutputFile, + + # Ignore any proxy settings when running the cmdlet + [Parameter()] + [switch] + $NoProxy, + + # Specifiy alternative Cumulocity session to use when running the cmdlet + [Parameter()] + [string] + $Session, + + # TimeoutSec timeout in seconds before a request will be aborted + [Parameter()] + [double] + $TimeoutSec, + + # Don't prompt for confirmation + [Parameter()] + [switch] + $Force + ) + + Begin { + $Parameters = @{} + if ($PSBoundParameters.ContainsKey("Application")) { + $Parameters["application"] = $Application + } + if ($PSBoundParameters.ContainsKey("ProcessingMode")) { + $Parameters["processingMode"] = $ProcessingMode + } + if ($PSBoundParameters.ContainsKey("OutputFile")) { + $Parameters["outputFile"] = $OutputFile + } + if ($PSBoundParameters.ContainsKey("NoProxy")) { + $Parameters["noProxy"] = $NoProxy + } + if ($PSBoundParameters.ContainsKey("Session")) { + $Parameters["session"] = $Session + } + if ($PSBoundParameters.ContainsKey("TimeoutSec")) { + $Parameters["timeout"] = $TimeoutSec * 1000 + } + + if ($env:C8Y_DISABLE_INHERITANCE -ne $true) { + # Inherit preference variables + Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + } + } + + Process { + foreach ($item in (PSc8y\Expand-Id $BinaryId)) { + if ($item) { + $Parameters["binaryId"] = if ($item.id) { $item.id } else { $item } + } + + if (!$Force -and + !$WhatIfPreference -and + !$PSCmdlet.ShouldProcess( + (PSc8y\Get-C8ySessionProperty -Name "tenant"), + (Format-ConfirmationMessage -Name $PSCmdlet.MyInvocation.InvocationName -InputObject $item) + )) { + continue + } + + Invoke-ClientCommand ` + -Noun "applications" ` + -Verb "deleteApplicationBinary" ` + -Parameters $Parameters ` + -Type "" ` + -ItemType "" ` + -ResultProperty "" ` + -Raw:$Raw + } + } + + End {} +} diff --git a/tools/PSc8y/Tests/Remove-ApplicationBinary.auto.Tests.ps1 b/tools/PSc8y/Tests/Remove-ApplicationBinary.auto.Tests.ps1 new file mode 100644 index 000000000..af4924131 --- /dev/null +++ b/tools/PSc8y/Tests/Remove-ApplicationBinary.auto.Tests.ps1 @@ -0,0 +1,27 @@ +. $PSScriptRoot/imports.ps1 + +Describe -Name "Remove-ApplicationBinary" { + BeforeEach { + $app = New-TestHostedApplication + New-ApplicationBinary -Id $app -File + $appBinary = Get-ApplicationBinaryCollection -Id $App.id + + } + + It -Skip "Remove an application binary related to a Hosted (web) application" { + $Response = PSc8y\Remove-ApplicationBinary -Application $app.id -BinaryId $appBinary.id + $LASTEXITCODE | Should -Be 0 + } + + It -Skip "Remove all application binaries (except for the active one) for an application (using pipeline)" { + $Response = PSc8y\Get-ApplicationBinaryCollection -Id $app.id | Remove-ApplicationBinary -Application $app.id + $LASTEXITCODE | Should -Be 0 + } + + + AfterEach { + Remove-Application -Id $app.id + + } +} +