Skip to content

Commit

Permalink
up will now package serverless templates and package doesn’t crea…
Browse files Browse the repository at this point in the history
…te changesets
  • Loading branch information
aidansteele committed Jun 18, 2019
1 parent bdc0186 commit eb43d0b
Show file tree
Hide file tree
Showing 16 changed files with 415 additions and 655 deletions.
75 changes: 0 additions & 75 deletions cmd/execute.go

This file was deleted.

97 changes: 0 additions & 97 deletions cmd/load_save.go

This file was deleted.

20 changes: 0 additions & 20 deletions cmd/load_save_test.go

This file was deleted.

110 changes: 63 additions & 47 deletions cmd/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,63 +18,44 @@ import (
"bytes"
"context"
"fmt"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/glassechidna/stackit/pkg/stackit"
"github.com/glassechidna/stackit/pkg/stackit/packager"
"github.com/olekukonko/tablewriter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"text/template"
)

func packageTemplate(ctx context.Context, region, profile, stackName, templatePath string, tags, parameters map[string]string, writer io.Writer) error {
absPath, err := filepath.Abs(templatePath)
if err != nil {
return errors.Wrapf(err, "determining absolute path of '%s'", templatePath)
}
if _, err := os.Stat(absPath); os.IsNotExist(err) {
return errors.Errorf("no file exists at %s", absPath)
}

sess := awsSession(profile, region)
sit := stackit.NewStackit(cloudformation.New(sess), sts.New(sess))

func packageTemplate(ctx context.Context, sess *session.Session, prefix string, templateReader packager.TemplateReader, writer io.Writer) (*string, error) {
s3api := s3.New(sess)
if region == "" && s3api.Config.Region != nil {
region = *s3api.Config.Region
pkger := packager.New(s3api, sts.New(sess), *s3api.Config.Region)
packagedTemplate, err := pkger.Package(ctx, prefix, templateReader, writer)
if err != nil {
return nil, errors.Wrap(err, "packaging template")
}

packager := stackit.NewPackager(s3api, sts.New(sess), region)

events := make(chan stackit.TailStackEvent)
return packagedTemplate, nil

printerCtx, printerCancel := context.WithCancel(ctx)
defer printerCancel()
go printUntilDone(printerCtx, events, writer)

upInput, err := packager.Package(stackName, absPath, tags, parameters)
if err != nil {
return errors.Wrap(err, "packaging template")
}
}

prepared, err := sit.Prepare(ctx, *upInput, events)
func writePackagedTemplateFile(absPath string, packagedTemplate *string, writer io.Writer) error {
base := fmt.Sprintf("%s.packaged.yml", strings.TrimSuffix(filepath.Base(absPath), filepath.Ext(absPath)))
packagedPath := filepath.Join(filepath.Dir(absPath), base)
err := ioutil.WriteFile(packagedPath, []byte(*packagedTemplate), 0644)
if err != nil {
panic(err)
}

if prepared == nil {
return nil // no-op change set
return errors.Wrap(err, "writing packaged template")
}

io.WriteString(writer, userFriendlyChangesOutput(prepared))

err = savePreparedOutput(prepared)
return errors.Wrap(err, "saving packaged output")
_, err = fmt.Fprintf(writer, "Wrote rendered template to %s\n", packagedPath)
return err
}

func userFriendlyChangesOutput(output *stackit.PrepareOutput) string {
Expand Down Expand Up @@ -116,35 +97,70 @@ Changes:
func init() {
cmd := &cobra.Command{
Use: "package",
Short: "Package template and create change set",
Short: "Upload artifacts and render template",
Long: `
package will:
* Upload any local paths referenced in the template (complete list[1]) to S3
* Create a changeset from the transformed template
* Print out a list of the estimated changes that executing the template will cause
* Save to disk the change set ID for later execution of 'stackit execute'
* Create and save the transformed template to <template>.packaged.yml
[1]: https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html
`,
Run: func(cmd *cobra.Command, args []string) {
region, _ := cmd.PersistentFlags().GetString("region")
profile, _ := cmd.PersistentFlags().GetString("profile")
stackName, _ := cmd.PersistentFlags().GetString("stack-name")
templatePath, _ := cmd.PersistentFlags().GetString("template")
tagKvps, _ := cmd.PersistentFlags().GetStringSlice("tags")
tags := keyvalSliceToMap(tagKvps)
params := keyvalSliceToMap(args)
prefix, _ := cmd.PersistentFlags().GetString("prefix")

template, err := pathToTemplate(templatePath)
if err != nil {
fmt.Fprintf(cmd.OutOrStderr(), "%+v\n", err)
return
}

err := packageTemplate(context.Background(), region, profile, stackName, templatePath, tags, params, cmd.OutOrStderr())
sess := awsSession(profile, region)
packagedTemplate, err := packageTemplate(context.Background(), sess, prefix, template, cmd.OutOrStderr())
if err != nil {
fmt.Fprintf(cmd.OutOrStderr(), "%+v\n", err)
return
}

writePackagedTemplateFile(template.Name(), packagedTemplate, cmd.OutOrStderr())
},
}

cmd.PersistentFlags().String("stack-name", "", "")
cmd.PersistentFlags().String("template", "", "")
cmd.PersistentFlags().StringSlice("tags", []string{}, "")
cmd.PersistentFlags().String("prefix", "", "")
RootCmd.AddCommand(cmd)
}

type templateReader struct {
body string
path string
}

func pathToTemplate(path string) (*templateReader, error) {
abs, err := filepath.Abs(path)
if err != nil {
return nil, errors.Wrapf(err, "determining absolute path of '%s'", path)
}

if _, err := os.Stat(abs); os.IsNotExist(err) {
return nil, errors.Errorf("no file exists at %s", abs)
}

body, err := ioutil.ReadFile(abs)
if err != nil {
return nil, err
}

return &templateReader{body: string(body), path: abs}, nil
}

func (t *templateReader) String() string {
return t.body
}

func (t *templateReader) Name() string {
return t.path
}
Loading

0 comments on commit eb43d0b

Please sign in to comment.