Skip to content

Commit

Permalink
Add the ability to upload and attach metafiles
Browse files Browse the repository at this point in the history
Signed-off-by: Pete Wall <pwall@vmware.com>
  • Loading branch information
Pete Wall authored and petewall committed Jun 16, 2022
1 parent 0360d0a commit e0df4c8
Show file tree
Hide file tree
Showing 19 changed files with 438 additions and 59 deletions.
5 changes: 5 additions & 0 deletions ci/tasks/test-chart-product.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,10 @@ run:
mkpcli attach chart --product "${PRODUCT_SLUG}" --product-version "${VERSION}" --create-version \
--chart chart/*.tgz --instructions "helm install it"
# Also attach a meta file
echo "{\"data\": \"totally a real config file\"}" > config.json
mkpcli attach metafile --product "${PRODUCT_SLUG}" --product-version "${VERSION}" \
--metafile config.json --metafile-type config
# Get the list of charts
mkpcli product list-assets --type chart --product "${PRODUCT_SLUG}" --product-version "${VERSION}" | grep $(basename -s .tgz chart/*.tgz)
4 changes: 4 additions & 0 deletions ci/tasks/test-container-image-product.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,9 @@ run:
--instructions "docker run ${TEST_IMAGE_REPO}:${TEST_IMAGE_TAG}"
fi
# Also attach a meta file
mkpcli attach metafile --product "${PRODUCT_SLUG}" --product-version "${VERSION}" \
--metafile $(which ls) --metafile-type cli --metafile-version 1.0.0
# Get the list of container images
mkpcli product list-assets --type image --product "${PRODUCT_SLUG}" --product-version "${VERSION}" | grep "${TEST_IMAGE_REPO}:${TEST_IMAGE_TAG}"
5 changes: 5 additions & 0 deletions ci/tasks/test-vm-product.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ run:
mkpcli attach vm --product "${PRODUCT_SLUG}" --product-version "${VERSION}" --create-version \
--file "${VM_FILE}"
# Also attach a meta file
echo "some other virtual machine" > other-vm.iso
mkpcli attach metafile --product "${PRODUCT_SLUG}" --product-version "${VERSION}" \
--metafile other-vm.iso --metafile-type other --metafile-version 1.0.0
# Get the list of virtual machine files
mkpcli product list-assets --type vm --product "${PRODUCT_SLUG}" --product-version "${VERSION}" | grep $(basename -s .iso $(basename -s .ova "$VM_FILE"))
43 changes: 43 additions & 0 deletions cmd/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ var (
AttachContainerImageTag string
AttachContainerImageTagType string

AttachMetaFile string
AttachMetaFileVersion string

AttachVMFile string

AttachInstructions string
Expand All @@ -37,6 +40,7 @@ func init() {
rootCmd.AddCommand(AttachCmd)
AttachCmd.AddCommand(AttachChartCmd)
AttachCmd.AddCommand(AttachContainerImageCmd)
AttachCmd.AddCommand(AttachMetaFileCmd)
AttachCmd.AddCommand(AttachVMCmd)

AttachChartCmd.Flags().StringVarP(&AttachProductSlug, "product", "p", "", "Product slug (required)")
Expand Down Expand Up @@ -64,6 +68,14 @@ func init() {
AttachContainerImageCmd.Flags().BoolVar(&AttachCreateVersion, "create-version", false, "Create the product version, if it doesn't already exist")
AttachContainerImageCmd.Flags().StringVar(&AttachPCAFile, "pca-file", "", "Path to a PCA file to upload")

AttachMetaFileCmd.Flags().StringVarP(&AttachProductSlug, "product", "p", "", "Product slug (required)")
_ = AttachMetaFileCmd.MarkFlagRequired("product")
AttachMetaFileCmd.Flags().StringVarP(&AttachProductVersion, "product-version", "v", "", "Product version (default to latest version)")
AttachMetaFileCmd.Flags().StringVar(&AttachMetaFile, "metafile", "", "Meta file to upload (required)")
_ = AttachMetaFileCmd.MarkFlagRequired("metafile")
AttachMetaFileCmd.Flags().StringVar(&MetaFileType, "metafile-type", "", "Meta file version (required, one of "+strings.Join(metaFileTypesList(), ", ")+")")
AttachMetaFileCmd.Flags().StringVar(&AttachMetaFileVersion, "metafile-version", "", "Meta file type (default is the product version)")

AttachVMCmd.Flags().StringVarP(&AttachProductSlug, "product", "p", "", "Product slug (required)")
_ = AttachVMCmd.MarkFlagRequired("product")
AttachVMCmd.Flags().StringVarP(&AttachProductVersion, "product-version", "v", "", "Product version (default to latest version)")
Expand Down Expand Up @@ -190,6 +202,37 @@ var AttachContainerImageCmd = &cobra.Command{
},
}

var AttachMetaFileCmd = &cobra.Command{
Use: "metafile",
Short: "Attach a meta file",
Long: "Upload and attach a meta file to a product in the VMware Marketplace",
Example: fmt.Sprintf("%s attach metafile -p hyperspace-database-vm1 -v 1.2.3 --file deploy.sh", AppName),
Args: cobra.NoArgs,
PreRunE: RunSerially(ValidateMetaFileType, GetRefreshToken),
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

product, version, err := Marketplace.GetProductWithVersion(AttachProductSlug, AttachProductVersion)
if err != nil {
if errors.Is(err, &pkg.VersionDoesNotExistError{}) && AttachCreateVersion {
version = product.NewVersion(AttachProductVersion)
} else {
return err
}
}

if AttachMetaFileVersion == "" {
AttachMetaFileVersion = version.Number
}
updatedProduct, err := Marketplace.AttachMetaFile(AttachMetaFile, metaFileTypeMapping[MetaFileType], AttachMetaFileVersion, product, version)
if err != nil {
return err
}

return Output.RenderAssets(pkg.GetAssets(updatedProduct, version.Number))
},
}

var AttachVMCmd = &cobra.Command{
Use: "vm",
Short: "Attach a virtual machine file (ISO or OVA)",
Expand Down
9 changes: 4 additions & 5 deletions cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ var (
DownloadProductVersion string
DownloadFilter string
DownloadFilename string
DownloadType string
DownloadAcceptEULA bool
)

Expand All @@ -27,7 +26,7 @@ func init() {
_ = DownloadCmd.MarkFlagRequired("product")
DownloadCmd.Flags().StringVarP(&DownloadProductVersion, "product-version", "v", "", "Product version (default to latest version)")
DownloadCmd.Flags().StringVar(&DownloadFilter, "filter", "", "Filter assets by display name")
DownloadCmd.Flags().StringVarP(&DownloadType, "type", "t", "", "Filter assets by type (one of "+strings.Join(assetTypesList(), ", ")+")")
DownloadCmd.Flags().StringVarP(&AssetType, "type", "t", "", "Filter assets by type (one of "+strings.Join(assetTypesList(), ", ")+")")
DownloadCmd.Flags().StringVarP(&DownloadFilename, "filename", "f", "", "Output file name")
DownloadCmd.Flags().BoolVar(&DownloadAcceptEULA, "accept-eula", false, "Accept the product EULA")
}
Expand Down Expand Up @@ -57,11 +56,11 @@ var DownloadCmd = &cobra.Command{
}

assetType := ""
if DownloadType != "" {
assetType = typeMapping[DownloadType] + " "
if AssetType != "" {
assetType = assetTypeMapping[AssetType] + " "
}
var asset *pkg.Asset
assets := pkg.GetAssetsByType(typeMapping[DownloadType], product, version.Number)
assets := pkg.GetAssetsByType(assetTypeMapping[AssetType], product, version.Number)
if len(assets) == 0 {
return fmt.Errorf("product %s %s does not have any downloadable %sassets", product.Slug, version.Number, assetType)
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var _ = Describe("DownloadCmd", func() {
"0.0.0", // No assets
"1.1.1", // One asset
"3.3.3", // Multiple assets
"4.4.4", // VMs and Metafiles
"4.4.4", // VMs and MetaFiles
)

product.AddFile(test.CreateFakeOVA("my-db.ova", "1.1.1"))
Expand All @@ -58,7 +58,7 @@ var _ = Describe("DownloadCmd", func() {

cmd.DownloadFilename = ""
cmd.DownloadFilter = ""
cmd.DownloadType = ""
cmd.AssetType = ""
})

It("downloads the asset", func() {
Expand Down Expand Up @@ -115,7 +115,7 @@ var _ = Describe("DownloadCmd", func() {
It("returns an error saying there are no assets", func() {
cmd.DownloadProductSlug = "my-super-product"
cmd.DownloadProductVersion = "1.1.1"
cmd.DownloadType = "addon"
cmd.AssetType = "addon"
cmd.DownloadAcceptEULA = true
err := cmd.DownloadCmd.RunE(cmd.DownloadCmd, []string{""})
Expect(err).To(HaveOccurred())
Expand Down Expand Up @@ -180,7 +180,7 @@ var _ = Describe("DownloadCmd", func() {
It("returns a more specific error", func() {
cmd.DownloadProductSlug = "my-super-product"
cmd.DownloadProductVersion = "0.0.0"
cmd.DownloadType = "vm"
cmd.AssetType = "vm"
cmd.DownloadAcceptEULA = true
err := cmd.DownloadCmd.RunE(cmd.DownloadCmd, []string{""})
Expect(err).To(HaveOccurred())
Expand Down Expand Up @@ -209,7 +209,7 @@ var _ = Describe("DownloadCmd", func() {
It("returns a more specific error", func() {
cmd.DownloadProductSlug = "my-super-product"
cmd.DownloadProductVersion = "3.3.3"
cmd.DownloadType = "vm"
cmd.AssetType = "vm"
cmd.DownloadAcceptEULA = true
err := cmd.DownloadCmd.RunE(cmd.DownloadCmd, []string{""})
Expect(err).To(HaveOccurred())
Expand Down Expand Up @@ -271,7 +271,7 @@ var _ = Describe("DownloadCmd", func() {
cmd.DownloadProductSlug = "my-super-product"
cmd.DownloadProductVersion = "3.3.3"
cmd.DownloadFilter = "txt"
cmd.DownloadType = "vm"
cmd.AssetType = "vm"
cmd.DownloadAcceptEULA = true
err := cmd.DownloadCmd.RunE(cmd.DownloadCmd, []string{""})
Expect(err).To(HaveOccurred())
Expand All @@ -285,7 +285,7 @@ var _ = Describe("DownloadCmd", func() {
It("downloads the asset of the given type", func() {
cmd.DownloadProductSlug = "my-super-product"
cmd.DownloadProductVersion = "4.4.4"
cmd.DownloadType = "metafile"
cmd.AssetType = "metafile"
cmd.DownloadAcceptEULA = true
err := cmd.DownloadCmd.RunE(cmd.DownloadCmd, []string{""})
Expect(err).ToNot(HaveOccurred())
Expand Down
17 changes: 8 additions & 9 deletions cmd/products.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import (
)

var (
allOrgs = false
searchTerm string
ProductSlug string
ProductVersion string
ListAssetsByType string
SetOSLFile string
allOrgs = false
searchTerm string
ProductSlug string
ProductVersion string
SetOSLFile string
)

func init() {
Expand All @@ -39,7 +38,7 @@ func init() {
ListAssetsCmd.Flags().StringVarP(&ProductSlug, "product", "p", "", "Product slug (required)")
_ = ListAssetsCmd.MarkFlagRequired("product")
ListAssetsCmd.Flags().StringVarP(&ProductVersion, "product-version", "v", "", "Product version")
ListAssetsCmd.Flags().StringVarP(&ListAssetsByType, "type", "t", "", "Filter assets by type (one of "+strings.Join(assetTypesList(), ", ")+")")
ListAssetsCmd.Flags().StringVarP(&AssetType, "type", "t", "", "Filter assets by type (one of "+strings.Join(assetTypesList(), ", ")+")")

ListProductVersionsCmd.Flags().StringVarP(&ProductSlug, "product", "p", "", "Product slug (required)")
_ = ListProductVersionsCmd.MarkFlagRequired("product")
Expand Down Expand Up @@ -128,11 +127,11 @@ var ListAssetsCmd = &cobra.Command{
}

var assets []*pkg.Asset
if ListAssetsByType == "" {
if AssetType == "" {
assets = pkg.GetAssets(product, version.Number)
Output.PrintHeader(fmt.Sprintf("Assets for for %s %s:", product.DisplayName, version.Number))
} else {
assetType := typeMapping[ListAssetsByType]
assetType := assetTypeMapping[AssetType]
assets = pkg.GetAssetsByType(assetType, product, version.Number)
Output.PrintHeader(fmt.Sprintf("%s assets for for %s %s:", assetType, product.DisplayName, version.Number))
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/products_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ var _ = Describe("Products", func() {
It("outputs the list of assets", func() {
cmd.ProductSlug = "my-super-product"
cmd.ProductVersion = "1"
cmd.ListAssetsByType = ""
cmd.AssetType = ""
err := cmd.ListAssetsCmd.RunE(cmd.ListAssetsCmd, []string{})
Expect(err).ToNot(HaveOccurred())

Expand All @@ -188,7 +188,7 @@ var _ = Describe("Products", func() {
It("outputs the filtered list of assets", func() {
cmd.ProductSlug = "my-super-product"
cmd.ProductVersion = "1"
cmd.ListAssetsByType = "vm"
cmd.AssetType = "vm"
err := cmd.ListAssetsCmd.RunE(cmd.ListAssetsCmd, []string{})
Expect(err).ToNot(HaveOccurred())

Expand Down
37 changes: 32 additions & 5 deletions cmd/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,57 @@ import (
var (
Marketplace pkg.MarketplaceInterface
Output output.Format
typeMapping = map[string]string{

AssetType string
assetTypeMapping = map[string]string{
"addon": pkg.AssetTypeAddon,
"chart": pkg.AssetTypeChart,
"image": pkg.AssetTypeContainerImage,
"metafile": pkg.AssetTypeMetaFile,
"vm": pkg.AssetTypeVM,
}
MetaFileType string
metaFileTypeMapping = map[string]string{
"cli": pkg.MetaFileTypeCLI,
"config": pkg.MetaFileTypeConfig,
"other": pkg.MetaFileTypeOther,
}
)

func assetTypesList() []string {
var assetTypes []string
for assetType := range typeMapping {
for assetType := range assetTypeMapping {
assetTypes = append(assetTypes, assetType)
}
sort.Strings(assetTypes)
return assetTypes
}

func ValidateAssetTypeFilter(cmd *cobra.Command, args []string) error {
if ListAssetsByType == "" {
if AssetType == "" {
return nil
}
if assetTypeMapping[AssetType] != "" {
return nil
}
return fmt.Errorf("Unknown asset type: %s\nPlease use one of %s", AssetType, strings.Join(assetTypesList(), ", "))
}

func metaFileTypesList() []string {
var metaFileTypes []string
for metaFileType := range metaFileTypeMapping {
metaFileTypes = append(metaFileTypes, metaFileType)
}
sort.Strings(metaFileTypes)
return metaFileTypes
}

func ValidateMetaFileType(cmd *cobra.Command, args []string) error {
if MetaFileType == "" {
return nil
}
if typeMapping[ListAssetsByType] != "" {
if metaFileTypeMapping[MetaFileType] != "" {
return nil
}
return fmt.Errorf("Unknown asset type: %s\nPlease use one of %s", ListAssetsByType, strings.Join(assetTypesList(), ", "))
return fmt.Errorf("Unknown meta file type: %s\nPlease use one of %s", MetaFileType, strings.Join(metaFileTypesList(), ", "))
}
58 changes: 38 additions & 20 deletions cmd/shared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,46 @@ import (
"github.com/vmware-labs/marketplace-cli/v2/cmd"
)

var _ = Describe("Products", func() {
Describe("ValidateAssetTypeFilter", func() {
It("allows valid asset types", func() {
cmd.ListAssetsByType = "addon"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.ListAssetsByType = "chart"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.ListAssetsByType = "image"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.ListAssetsByType = "metafile"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.ListAssetsByType = "vm"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
var _ = Describe("ValidateAssetTypeFilter", func() {
It("allows valid asset types", func() {
cmd.AssetType = "addon"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.AssetType = "chart"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.AssetType = "image"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.AssetType = "metafile"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
cmd.AssetType = "vm"
Expect(cmd.ValidateAssetTypeFilter(nil, nil)).To(Succeed())
})

When("an invalid asset type is used", func() {
It("returns an error", func() {
cmd.AssetType = "dogfood"
err := cmd.ValidateAssetTypeFilter(nil, nil)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("Unknown asset type: dogfood\nPlease use one of addon, chart, image, metafile, vm"))
})
})
})

var _ = Describe("ValidateMetaFileType", func() {
It("allows valid meta file types", func() {
cmd.MetaFileType = "cli"
Expect(cmd.ValidateMetaFileType(nil, nil)).To(Succeed())
cmd.MetaFileType = "config"
Expect(cmd.ValidateMetaFileType(nil, nil)).To(Succeed())
cmd.MetaFileType = "other"
Expect(cmd.ValidateMetaFileType(nil, nil)).To(Succeed())
})

When("an invalid asset type is used", func() {
It("returns an error", func() {
cmd.ListAssetsByType = "dogfood"
err := cmd.ValidateAssetTypeFilter(nil, nil)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("Unknown asset type: dogfood\nPlease use one of addon, chart, image, metafile, vm"))
})
When("an invalid meta file type is used", func() {
It("returns an error", func() {
cmd.MetaFileType = "dogfood"
err := cmd.ValidateMetaFileType(nil, nil)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("Unknown meta file type: dogfood\nPlease use one of cli, config, other"))
})
})
})

0 comments on commit e0df4c8

Please sign in to comment.