Skip to content
Merged
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
59 changes: 32 additions & 27 deletions cmd/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bufio"
"context"
"fmt"
"log"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -73,11 +72,14 @@ func NewCmdBundle() *cobra.Command {
Use: "new",
Short: "Create a new bundle from a template",
Long: helpdocs.MustRender("bundle/new"),
Run: func(cmd *cobra.Command, args []string) { runBundleNew(&bundleNewInput) },
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
return runBundleNew(&bundleNewInput)
},
}
bundleNewCmd.Flags().StringVarP(&bundleNewInput.name, "name", "n", "", "Name of the new bundle")
bundleNewCmd.Flags().StringVarP(&bundleNewInput.name, "name", "n", "", "Name of the new bundle. Setting this along with --template-name will disable the interactive prompt.")
bundleNewCmd.Flags().StringVarP(&bundleNewInput.description, "description", "d", "", "Description of the new bundle")
bundleNewCmd.Flags().StringVarP(&bundleNewInput.templateName, "template-name", "t", "", "Name of the bundle template to use")
bundleNewCmd.Flags().StringVarP(&bundleNewInput.templateName, "template-name", "t", "", "Name of the bundle template to use. Setting this along with --name will disable the interactive prompt.")
bundleNewCmd.Flags().StringSliceVarP(&bundleNewInput.connections, "connections", "c", []string{}, "Connections and names to add to the bundle - example: network=massdriver/vpc")
bundleNewCmd.Flags().StringVarP(&bundleNewInput.outputDir, "output-directory", "o", ".", "Directory to output the new bundle")
bundleNewCmd.Flags().StringVarP(&bundleNewInput.paramsDir, "params-directory", "p", "", "Path with existing params to use - opentofu module directory or helm chart values.yaml")
Expand Down Expand Up @@ -199,31 +201,31 @@ func runBundleNewFlags(input *bundleNew) (*templatecache.TemplateData, error) {
return templateData, nil
}

func runBundleNew(input *bundleNew) {
func runBundleNew(input *bundleNew) error {
ctx := context.Background()

cache, err := templatecache.NewBundleTemplateCache(templatecache.GithubTemplatesFetcher)
if err != nil {
log.Fatal(err)
cache, cacheErr := templatecache.NewBundleTemplateCache(templatecache.GithubTemplatesFetcher)
if cacheErr != nil {
return fmt.Errorf("error initializing template cache: %w", cacheErr)
}

// If MD_TEMPLATES_PATH is set then it's most likely local dev work on templates so don't fetch
// or the refresh will overwrite whatever path this points to
if os.Getenv("MD_TEMPLATES_PATH") == "" {
err = templates.RunRefresh(cache)
if err != nil {
log.Fatal(err)
refreshErr := templates.RunRefresh(cache)
if refreshErr != nil {
return fmt.Errorf("error refreshing template cache: %w", refreshErr)
}
}

mdClient, mdClientErr := client.New()
if mdClientErr != nil {
log.Fatal(fmt.Errorf("error initializing massdriver client: %w", mdClientErr))
return fmt.Errorf("error initializing massdriver client: %w", mdClientErr)
}

artifactDefs, err := api.ListArtifactDefinitions(ctx, mdClient)
if err != nil {
log.Fatal(err)
artifactDefs, listErr := api.ListArtifactDefinitions(ctx, mdClient)
if listErr != nil {
return fmt.Errorf("error listing artifact definitions: %w", listErr)
}

artifactDefinitions := map[string]map[string]any{}
Expand All @@ -237,30 +239,33 @@ func runBundleNew(input *bundleNew) {
bundle.SetMassdriverArtifactDefinitions(artifactDefinitions)

var templateData *templatecache.TemplateData
var runErr error
if input.name == "" || input.templateName == "" {
// run the interactive prompt
templateData, err = runBundleNewInteractive(input.outputDir)
if err != nil {
log.Fatal(err)
templateData, runErr = runBundleNewInteractive(input.outputDir)
if runErr != nil {
return fmt.Errorf("error running interactive prompt: %w", runErr)
}
} else {
// skip the interactive prompt and use flags
templateData, err = runBundleNewFlags(input)
if err != nil {
log.Fatal(err)
templateData, runErr = runBundleNewFlags(input)
if runErr != nil {
return fmt.Errorf("error running flags: %w", runErr)
}
}

localParams, err := params.GetFromPath(templateData.TemplateName, templateData.ExistingParamsPath)
if err != nil {
log.Fatal(err)
localParams, paramsErr := params.GetFromPath(templateData.TemplateName, templateData.ExistingParamsPath)
if paramsErr != nil {
return fmt.Errorf("error getting params from path: %w", paramsErr)
}

templateData.ParamsSchema = localParams

if err = cmdbundle.RunNew(cache, templateData); err != nil {
log.Fatal(err)
if newErr := cmdbundle.RunNew(cache, templateData); newErr != nil {
return fmt.Errorf("error running bundle new: %w", newErr)
}

fmt.Printf("Bundle %q created successfully at path %q\n", templateData.Name, templateData.OutputDir)
return nil
}

func runBundleBuild(cmd *cobra.Command, args []string) error {
Expand Down
4 changes: 2 additions & 2 deletions docs/generated/mass_bundle_new.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ mass bundle new [flags]
-c, --connections strings Connections and names to add to the bundle - example: network=massdriver/vpc
-d, --description string Description of the new bundle
-h, --help help for new
-n, --name string Name of the new bundle
-n, --name string Name of the new bundle. Setting this will disable the interactive prompt.
-o, --output-directory string Directory to output the new bundle (default ".")
-p, --params-directory string Path with existing params to use - opentofu module directory or helm chart values.yaml
-t, --template-name string Name of the bundle template to use
-t, --template-name string Name of the bundle template to use. Setting this will disable the interactive prompt.
```

### SEE ALSO
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/go-resty/resty/v2 v2.16.5
github.com/itchyny/gojq v0.12.16
github.com/manifoldco/promptui v0.9.0
github.com/massdriver-cloud/airlock v0.0.6
github.com/massdriver-cloud/airlock v0.0.7
github.com/massdriver-cloud/massdriver-sdk-go v0.0.7
github.com/moby/moby v27.3.1+incompatible
github.com/moby/term v0.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/massdriver-cloud/airlock v0.0.6 h1:XGNDwZDr/EeGGDQnxM/oovXBsmIoEALJU0cBzZI+Ags=
github.com/massdriver-cloud/airlock v0.0.6/go.mod h1:VULNe2TXFGexs2YtEPOtp2PNFq9eq1LOK5UoXjJ/mOw=
github.com/massdriver-cloud/airlock v0.0.7 h1:mKCTaD53Eqz2vXt6ShXyI/QtNztgaldBW59mGWR4sEU=
github.com/massdriver-cloud/airlock v0.0.7/go.mod h1:VULNe2TXFGexs2YtEPOtp2PNFq9eq1LOK5UoXjJ/mOw=
github.com/massdriver-cloud/massdriver-sdk-go v0.0.7 h1:6mo2oFpQ/rqnhIp96Biz1TnfWtPYf2Lt0f62dBjTlAw=
github.com/massdriver-cloud/massdriver-sdk-go v0.0.7/go.mod h1:6bXMPQmfeKHD3Tm/cwnrkqiZaDEgRUUq0+uZckKRsbM=
github.com/massdriver-cloud/terraform-config-inspect v0.0.1 h1:eLtKFRaklHIxcPvUtZmNacl28n4QIHr29pJzw/u/FKU=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ type ArtifactDefinitionWithSchema struct {

func GetArtifactDefinition(ctx context.Context, mdClient *client.Client, name string) (*ArtifactDefinitionWithSchema, error) {
response, err := getArtifactDefinition(ctx, mdClient.GQL, mdClient.Config.OrganizationID, name)
return response.toArtifactDefinition(), err
if err != nil {
return nil, fmt.Errorf("failed to get artifact definition %s: %w", name, err)
}
return response.toArtifactDefinition(), nil
}

func (response *getArtifactDefinitionResponse) toArtifactDefinition() *ArtifactDefinitionWithSchema {
Expand All @@ -38,7 +41,10 @@ func (response *getArtifactDefinitionResponse) toArtifactDefinition() *ArtifactD

func ListArtifactDefinitions(ctx context.Context, mdClient *client.Client) ([]ArtifactDefinitionWithSchema, error) {
response, err := listArtifactDefinitions(ctx, mdClient.GQL, mdClient.Config.OrganizationID)
return response.toArtifactDefinitions(), err
if err != nil {
return nil, fmt.Errorf("failed to list artifact definitions: %w", err)
}
return response.toArtifactDefinitions(), nil
}

func (response *listArtifactDefinitionsResponse) toArtifactDefinitions() []ArtifactDefinitionWithSchema {
Expand All @@ -59,12 +65,12 @@ func (response *listArtifactDefinitionsResponse) toArtifactDefinitions() []Artif
func PublishArtifactDefinition(ctx context.Context, mdClient *client.Client, schema map[string]any) (*ArtifactDefinitionWithSchema, error) {
response, err := publishArtifactDefinition(ctx, mdClient.GQL, mdClient.Config.OrganizationID, schema)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to publish artifact definition: %w", err)
}
if !response.PublishArtifactDefinition.Successful {
return nil, fmt.Errorf("unable to publish artifact definition: %s", response.PublishArtifactDefinition.GetMessages()[0].Message)
}
return response.toArtifactDefinition(), err
return response.toArtifactDefinition(), nil
}

func (response *publishArtifactDefinitionResponse) toArtifactDefinition() *ArtifactDefinitionWithSchema {
Expand Down
10 changes: 8 additions & 2 deletions pkg/bundle/dereference.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ type DereferenceOptions struct {

// relativeFilePathPattern only accepts relative file path prefixes "./" and "../"
var relativeFilePathPattern = regexp.MustCompile(`^(\.\/|\.\.\/)`)
var massdriverDefinitionPattern = regexp.MustCompile(`^[a-zA-Z0-9]`)
var massdriverDefinitionPattern = regexp.MustCompile(`^[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+$`)
var httpPattern = regexp.MustCompile(`^(http|https)://`)
var fragmentPattern = regexp.MustCompile(`^#`)

func DereferenceSchema(anyVal any, opts DereferenceOptions) (any, error) {
val := getValue(anyVal)
Expand All @@ -89,7 +90,7 @@ func DereferenceSchema(anyVal any, opts DereferenceOptions) (any, error) {

var err error
if relativeFilePathPattern.MatchString(schemaRefValue) { //nolint:gocritic
// this is a local file ref
// this is a relative file ref
// build up the path from where the dir current schema was read
hydratedSchema, err = dereferenceFilePathRef(hydratedSchema, schema, schemaRefValue, opts)
} else if httpPattern.MatchString(schemaRefValue) {
Expand All @@ -98,6 +99,11 @@ func DereferenceSchema(anyVal any, opts DereferenceOptions) (any, error) {
} else if massdriverDefinitionPattern.MatchString(schemaRefValue) {
// this must be a published schema, so fetch from massdriver
hydratedSchema, err = dereferenceMassdriverRef(hydratedSchema, schema, schemaRefValue, opts)
} else if fragmentPattern.MatchString(schemaRefValue) {
// this is a fragment, so we do nothing and leave the schema as is
// since fragments are not dereferenced in the same way as full schemas
} else {
return nil, fmt.Errorf("unable to resolve ref: %s", schemaRefValue)
}
if err != nil {
return hydratedSchema, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/bundle/testdata/lint/module/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ variable "bar" {
}

variable "md_metadata" {
type = any
type = object({})
}
3 changes: 3 additions & 0 deletions pkg/params/params.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package params

import (
"fmt"
"path"

"github.com/massdriver-cloud/airlock/pkg/bicep"
Expand All @@ -20,6 +21,7 @@ func GetFromPath(templateName, paramsPath string) (string, error) {
err error
)

fmt.Printf("Importing params from %s...\n", paramsPath)
switch templateName {
case "terraform-module", "opentofu-module":
paramSchema, err = opentofu.TofuToSchema(paramsPath)
Expand Down Expand Up @@ -47,6 +49,7 @@ func GetFromPath(templateName, paramsPath string) (string, error) {
if err != nil {
return "", err
}
fmt.Println("Params schema imported successfully.")

return string(out), nil
}
Loading