Skip to content

Commit

Permalink
feat: list marketplace item versions (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
malta895 authored Nov 21, 2023
1 parent 844153b commit 17c3117
Show file tree
Hide file tree
Showing 7 changed files with 390 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- feat: add command `miactl marketplace list-versions`

### Fixed

- help text of version command
Expand Down
18 changes: 18 additions & 0 deletions docs/30_commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,21 @@ miactl marketplace apply -f myFantasticGoTemplates
-f, --file stringArray paths to JSON/YAML files or folder of files containing a Marketplace item definition
-h, --help help for apply
```

### list-versions (ALPHA)

:::warning

This command is in ALPHA state. This means that it can be subject to breaking changes in the next versions of miactl.

:::

List all the available versions of a specific Marketplace item.

#### Synopsis

The flag `--item-id` or `-i` accepts the `itemId` of the Item.

```
miactl marketplace list-versions -i some-item
```
7 changes: 7 additions & 0 deletions internal/clioptions/clioptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type CLIOptions struct {
OutputPath string

MarketplaceResourcePaths []string
MarketplaceItemID string

FromCronJob string

Expand Down Expand Up @@ -135,6 +136,12 @@ func (o *CLIOptions) AddMarketplaceApplyFlags(cmd *cobra.Command) {
}
}

func (o *CLIOptions) AddMarketplaceGetItemVersionsFlags(cmd *cobra.Command) string {
flagName := "item-id"
cmd.Flags().StringVarP(&o.MarketplaceItemID, flagName, "i", "", "The itemId of the item")
return flagName
}

func (o *CLIOptions) AddCreateJobFlags(flags *pflag.FlagSet) {
flags.StringVar(&o.FromCronJob, "from", "", "name of the cronjob to create a Job from")
}
Expand Down
1 change: 1 addition & 0 deletions internal/cmd/marketplace.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func MarketplaceCmd(options *clioptions.CLIOptions) *cobra.Command {
cmd.AddCommand(marketplace.GetCmd(options))
cmd.AddCommand(marketplace.DeleteCmd(options))
cmd.AddCommand(marketplace_apply.ApplyCmd(options))
cmd.AddCommand(marketplace.ListVersionCmd(options))

return cmd
}
132 changes: 132 additions & 0 deletions internal/cmd/marketplace/list_versions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright Mia srl
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package marketplace

import (
"context"
"errors"
"fmt"
"net/http"
"strings"

"github.com/mia-platform/miactl/internal/client"
"github.com/mia-platform/miactl/internal/clioptions"
"github.com/mia-platform/miactl/internal/resources/marketplace"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
)

const listItemVersionsEndpointTemplate = "/api/backend/marketplace/tenants/%s/resources/%s/versions"

var (
ErrItemNotFound = errors.New("item not found")
ErrGenericServerError = errors.New("server error while fetching item versions")
ErrMissingCompanyID = errors.New("companyID is required")
)

// ListVersionCmd return a new cobra command for listing marketplace item versions
func ListVersionCmd(options *clioptions.CLIOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "list-versions",
Short: "List versions of a Marketplace item (ALPHA)",
Long: `List the currently available versions of a Marketplace item.
The command will output a table with each version of the item.
This command is in ALPHA state. This means that it can be subject to breaking changes in the next versions of miactl.`,
Run: func(cmd *cobra.Command, args []string) {
restConfig, err := options.ToRESTConfig()
cobra.CheckErr(err)
client, err := client.APIClientForConfig(restConfig)
cobra.CheckErr(err)

releases, err := getItemVersions(
client,
restConfig.CompanyID,
options.MarketplaceItemID,
)
cobra.CheckErr(err)

table := buildItemVersionListTable(releases)

fmt.Println(table)
},
}

flagName := options.AddMarketplaceGetItemVersionsFlags(cmd)
err := cmd.MarkFlagRequired(flagName)
if err != nil {
// the error is only due to a programming error (missing command flag), hence panic
panic(err)
}

return cmd
}

func getItemVersions(client *client.APIClient, companyID, itemID string) (*[]marketplace.Release, error) {
if companyID == "" {
return nil, ErrMissingCompanyID
}
resp, err := client.
Get().
APIPath(
fmt.Sprintf(listItemVersionsEndpointTemplate, companyID, itemID),
).
Do(context.Background())

if err != nil {
return nil, fmt.Errorf("error executing request: %w", err)
}

switch resp.StatusCode() {
case http.StatusOK:
releases := &[]marketplace.Release{}
err = resp.ParseResponse(releases)
if err != nil {
return nil, fmt.Errorf("error parsing response body: %w", err)
}
return releases, nil
case http.StatusNotFound:
return nil, fmt.Errorf("%w: %s", ErrItemNotFound, itemID)
}
return nil, ErrGenericServerError
}

func buildItemVersionListTable(releases *[]marketplace.Release) string {
strBuilder := &strings.Builder{}
table := tablewriter.NewWriter(strBuilder)
table.SetBorders(tablewriter.Border{Left: false, Top: false, Right: false, Bottom: false})
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetRowSeparator("")
table.SetAutoWrapText(false)
table.SetHeader([]string{"Version", "Name", "Description"})

for _, release := range *releases {
description := "-"
if release.Description != "" {
description = release.Description
}
table.Append([]string{
release.Version,
release.Name,
description,
})
}
table.Render()

return strBuilder.String()
}
Loading

0 comments on commit 17c3117

Please sign in to comment.