forked from aws/aws-sam-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstart.go
160 lines (132 loc) · 4.87 KB
/
start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"github.com/awslabs/goformation/intrinsics"
"github.com/fatih/color"
"github.com/awslabs/aws-sam-local/router"
"github.com/awslabs/goformation"
"github.com/codegangsta/cli"
)
// messages color
var errMsg = color.New(color.FgRed).Add(color.Bold)
var warnMsg = color.New(color.FgYellow).Add(color.Bold)
var successMsg = color.New(color.FgGreen).Add(color.Bold)
func start(c *cli.Context) {
// Setup the logger
stderr := io.Writer(os.Stderr)
logarg := c.String("log-file")
if len(logarg) > 0 {
if logFile, err := os.Create(logarg); err == nil {
stderr = io.Writer(logFile)
log.SetOutput(stderr)
} else {
log.Fatalf("Failed to open log file %s: %s\n", c.String("log"), err)
}
}
filename := getTemplateFilename(c.String("template"))
template, err := goformation.OpenWithOptions(filename, &intrinsics.ProcessorOptions{
ParameterOverrides: parseParameters(c.String("parameter-values")),
})
if err != nil {
log.Fatalf("Failed to parse template: %s\n", err)
}
// Check connectivity to docker
dockerVersion, err := getDockerVersion()
if err != nil {
log.Printf("Running AWS SAM projects locally requires Docker. Have you got it installed?\n")
log.Printf("%s\n", err)
os.Exit(1)
}
log.Printf("Connected to Docker %s", dockerVersion)
// Get the working directory for the project based on
// the template directory. Also, give an opportunity for
// this to be overriden by the --docker-volume-basedir flag.
cwd := filepath.Dir(filename)
if c.String("docker-volume-basedir") != "" {
cwd = c.String("docker-volume-basedir")
}
// Create a new router
mux := router.NewServerlessRouter(c.Bool("prefix-routing"))
templateApis := template.GetAllAWSServerlessApiResources()
for _, api := range templateApis {
err := mux.AddAPI(&api)
if err != nil {
errMsg.Printf("%s\n\n", err.Error())
os.Exit(1)
}
}
functions := template.GetAllAWSServerlessFunctionResources()
for name, function := range functions {
cwd := filepath.Dir(filename)
if c.String("docker-volume-basedir") != "" {
cwd = c.String("docker-volume-basedir")
}
// Initiate a new Lambda runtime
runt, err := NewRuntime(NewRuntimeOpt{
Cwd: cwd,
LogicalID: name,
Function: function,
Logger: stderr,
EnvOverrideFile: c.String("env-vars"),
DebugPort: c.String("debug-port"),
SkipPullImage: c.Bool("skip-pull-image"),
DockerNetwork: c.String("docker-network"),
})
// Check there wasn't a problem initiating the Lambda runtime
if err != nil {
if err == ErrRuntimeNotSupported {
warnMsg.Printf("Ignoring %s (%s) due to unsupported runtime (%s)\n", name, function.Handler, function.Runtime)
continue
} else {
warnMsg.Printf("Ignoring %s (%s) due to %s runtime init error: %s\n", name, function.Handler, function.Runtime, err)
continue
}
}
// Add this AWS::Serverless::Function to the HTTP router
if err := mux.AddFunction(&function, runt.InvokeHTTP(c.String("profile"))); err != nil {
if err == router.ErrNoEventsFound {
warnMsg.Printf("Ignoring %s (%s) as no API event sources are defined\n", name, function.Handler)
}
}
}
// Check we actually mounted some functions on our HTTP router
if len(mux.Mounts()) < 1 {
if len(functions) < 1 {
errMsg.Fprintf(stderr, "ERROR: No Serverless functions were found in your SAM template.\n")
os.Exit(1)
}
errMsg.Fprintf(stderr, "ERROR: None of the Serverless functions in your SAM template were able to be mounted. See above for errors.\n")
os.Exit(1)
}
fmt.Fprintf(stderr, "\n")
for _, mount := range mux.Mounts() {
if mount.Function == nil || len(mount.Function.Handler) == 0 {
msg := warnMsg.Sprint(fmt.Sprintf("WARNING: Could not find function for %s to %s resource", mount.Methods(), mount.Path))
fmt.Fprintf(os.Stderr, "%s\n", msg)
continue
}
msg := successMsg.Sprintf("Mounting %s (%s) at http://%s:%s%s %s", mount.Function.Handler, mount.Function.Runtime, c.String("host"), c.String("port"), mount.Path, mount.Methods())
fmt.Fprintf(os.Stderr, "%s\n", msg)
}
// Mount static files
if c.String("static-dir") != "" {
static := filepath.Join(cwd, c.String("static-dir"))
if _, err := os.Stat(static); err == nil {
fmt.Fprintf(os.Stderr, "Mounting static files from %s at /\n", static)
mux.AddStaticDir(static)
}
}
fmt.Fprintf(stderr, "\n")
fmt.Fprintf(stderr, "You can now browse to the above endpoints to invoke your functions.\n")
fmt.Fprintf(stderr, "You do not need to restart/reload SAM CLI while working on your functions,\n")
fmt.Fprintf(stderr, "changes will be reflected instantly/automatically. You only need to restart\n")
fmt.Fprintf(stderr, "SAM CLI if you update your AWS SAM template.\n")
fmt.Fprintf(stderr, "\n")
// Start the HTTP listener
log.Fatal(http.ListenAndServe(c.String("host")+":"+c.String("port"), mux.Router()))
}