sumomo 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/sumomo/api_modules/real_script.js +51 -0
- data/data/sumomo/api_modules/test_script.js +146 -0
- data/data/sumomo/custom_resources/APIDomainName.js +1 -0
- data/exe/sumomo +13 -1
- data/lib/sumomo.rb +44 -0
- data/lib/sumomo/api.rb +11 -57
- data/lib/sumomo/ecs.rb +8 -0
- data/lib/sumomo/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82038b259fd91406f002951849bd381049ab781f
|
4
|
+
data.tar.gz: 7ab6b857aab5696045677d6e46f28d39a2534b05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97951e0b224355cc51028f4ddbc21f3d826aa9f3d9e5dd8b2b859f326f55597e743f5469cbb56b8332b3a99138dbe12028d2639f33609bfc5db6babbacc18420
|
7
|
+
data.tar.gz: 0c532926c529ae656dc2a65966ddaa23724caa930add7f2c485ffe7002cad0894358c6b74beea59eef3c94ba2c94e93d8169c1996e3c55f8a9e6a7732858638e
|
@@ -0,0 +1,51 @@
|
|
1
|
+
'use strict';
|
2
|
+
console.log('Loading API');
|
3
|
+
|
4
|
+
var os = require('os');
|
5
|
+
var http = require('http');
|
6
|
+
var url = require('url');
|
7
|
+
var merge = require('utils-merge');
|
8
|
+
var Router = require('router')
|
9
|
+
|
10
|
+
var router = Router();
|
11
|
+
|
12
|
+
function prepare(handler)
|
13
|
+
{
|
14
|
+
return function(request, callback)
|
15
|
+
{
|
16
|
+
try
|
17
|
+
{
|
18
|
+
request._native_req.pathParameters = request.params
|
19
|
+
handler(request._native_req, callback);
|
20
|
+
}
|
21
|
+
catch (e)
|
22
|
+
{
|
23
|
+
console.log(e);
|
24
|
+
callback(e, {
|
25
|
+
statusCode: 500,
|
26
|
+
body: JSON.stringify({message: "Internal Server Error"}, null, 2)
|
27
|
+
});
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
// {{ ROUTES }}
|
33
|
+
|
34
|
+
exports.handler = function(event, context, callback) {
|
35
|
+
|
36
|
+
var request = {
|
37
|
+
_native_req: event,
|
38
|
+
url: "https://something" + event.path,
|
39
|
+
method: event.httpMethod,
|
40
|
+
params: {}
|
41
|
+
}
|
42
|
+
|
43
|
+
console.log(request);
|
44
|
+
|
45
|
+
router(request, callback, function(err) {
|
46
|
+
callback(null, {
|
47
|
+
statusCode: 404,
|
48
|
+
body: JSON.stringify({message: "File not found"}, null, 2)
|
49
|
+
})
|
50
|
+
});
|
51
|
+
};
|
@@ -0,0 +1,146 @@
|
|
1
|
+
'use strict';
|
2
|
+
console.log('Loading API');
|
3
|
+
|
4
|
+
var os = require('os');
|
5
|
+
var finalhandler = require('finalhandler');
|
6
|
+
var http = require('http');
|
7
|
+
var url = require('url');
|
8
|
+
var merge = require('utils-merge');
|
9
|
+
var Router = require('router')
|
10
|
+
|
11
|
+
var router = Router();
|
12
|
+
|
13
|
+
var response_sent = false;
|
14
|
+
|
15
|
+
var server = http.createServer(function(req, res) {
|
16
|
+
|
17
|
+
var request = {
|
18
|
+
_native_req: req,
|
19
|
+
url: req.url,
|
20
|
+
method: req.method,
|
21
|
+
params: {}
|
22
|
+
}
|
23
|
+
|
24
|
+
router(request, res, function(err) {
|
25
|
+
|
26
|
+
res.statusCode = 404;
|
27
|
+
res.end(JSON.stringify({message: "File not found"}));
|
28
|
+
});
|
29
|
+
});
|
30
|
+
|
31
|
+
// Simulate API Gateway Lambda Proxy Event
|
32
|
+
function prepare(handler)
|
33
|
+
{
|
34
|
+
return function(request, res)
|
35
|
+
{
|
36
|
+
var body = [];
|
37
|
+
var req = request._native_req;
|
38
|
+
|
39
|
+
function callback(exception, response)
|
40
|
+
{
|
41
|
+
if (response.headers)
|
42
|
+
{
|
43
|
+
for (var key in response.headers)
|
44
|
+
{
|
45
|
+
res.setHeader(key, response.headers[key]);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
res.statusCode = response.statusCode || 404;
|
49
|
+
res.end(response.body || null);
|
50
|
+
}
|
51
|
+
|
52
|
+
req.on('data', function(chunk) {
|
53
|
+
body.push(chunk);
|
54
|
+
|
55
|
+
}).on('end', function() {
|
56
|
+
|
57
|
+
var completed_body = Buffer.concat(body).toString();
|
58
|
+
|
59
|
+
var parsed_url = url.parse(req.url, true);
|
60
|
+
|
61
|
+
var headers = {};
|
62
|
+
|
63
|
+
headers["Accept"] = "*/*";
|
64
|
+
headers["CloudFront-Forwarded-Proto"] = "https";
|
65
|
+
headers["CloudFront-Is-Desktop-Viewer"] = "true";
|
66
|
+
headers["CloudFront-Is-Mobile-Viewer"] = "false";
|
67
|
+
headers["CloudFront-Is-SmartTV-Viewer"] = "false";
|
68
|
+
headers["CloudFront-Is-Tablet-Viewer"] = "false";
|
69
|
+
headers["CloudFront-Viewer-Country"] = "US";
|
70
|
+
headers["Content-Type"] = "";
|
71
|
+
headers["Host"] = "";
|
72
|
+
headers["User-Agent"] = "";
|
73
|
+
headers["Via"] = "1.1 1234567890abcdefghijklmnopqrstuv.cloudfront.net (CloudFront)";
|
74
|
+
headers["X-Amz-Cf-Id"] = "0000000000000000000000000-000000000-000000000000000000==";
|
75
|
+
headers["X-Amzn-Trace-Id"] = "Root=1-00000000-ffffffffffffffffffffffff";
|
76
|
+
headers["X-Forwarded-For"] = req.connection.remoteAddress;
|
77
|
+
headers["X-Forwarded-Port"] = "443";
|
78
|
+
headers["X-Forwarded-Proto"] = "https";
|
79
|
+
|
80
|
+
for(var key in req.headers)
|
81
|
+
{
|
82
|
+
var uppercased = key.replace(/(^|-)[a-z]/g, function(text){ return text.toUpperCase(); });
|
83
|
+
|
84
|
+
headers[uppercased] = req.headers[key];
|
85
|
+
}
|
86
|
+
|
87
|
+
var request_event = {
|
88
|
+
resource: "/{proxy+}",
|
89
|
+
path: parsed_url.pathname,
|
90
|
+
httpMethod: req.method,
|
91
|
+
headers: headers,
|
92
|
+
queryStringParameters: url.parse(req.url, true).query,
|
93
|
+
pathParameters: req.params,
|
94
|
+
stageVariables: null,
|
95
|
+
requestContext: {
|
96
|
+
path: parsed_url.pathname,
|
97
|
+
accountId: "000000000000",
|
98
|
+
resourceId: "123abc",
|
99
|
+
stage: "test",
|
100
|
+
requestId: "00000000-0000-0000-0000-000000000000",
|
101
|
+
identity: {
|
102
|
+
cognitoIdentityId: null,
|
103
|
+
accountId: null,
|
104
|
+
cognitoIdentityId: null,
|
105
|
+
caller: null,
|
106
|
+
apiKey: "",
|
107
|
+
sourceIp: req.connection.remoteAddress,
|
108
|
+
accessKey: null,
|
109
|
+
cognitoAuthenticationType: null,
|
110
|
+
cognitoAuthenticationProvider: null,
|
111
|
+
userArn: null,
|
112
|
+
userAgent: headers["User-Agent"],
|
113
|
+
user: null
|
114
|
+
|
115
|
+
},
|
116
|
+
resourcePath: "/{proxy+}",
|
117
|
+
httpMethod: req.method,
|
118
|
+
apiId: "12345abcde"
|
119
|
+
},
|
120
|
+
|
121
|
+
body: completed_body,
|
122
|
+
isBase64Encoded: false
|
123
|
+
|
124
|
+
};
|
125
|
+
|
126
|
+
req._native_req = undefined;
|
127
|
+
|
128
|
+
try
|
129
|
+
{
|
130
|
+
handler(request_event, callback);
|
131
|
+
}
|
132
|
+
catch (e)
|
133
|
+
{
|
134
|
+
console.log(e);
|
135
|
+
callback(e, {
|
136
|
+
statusCode: 500,
|
137
|
+
body: JSON.stringify({message: "Internal Server Error"}, null, 2)
|
138
|
+
});
|
139
|
+
}
|
140
|
+
});
|
141
|
+
};
|
142
|
+
}
|
143
|
+
|
144
|
+
// {{ ROUTES }}
|
145
|
+
|
146
|
+
server.listen(3000)
|
data/exe/sumomo
CHANGED
@@ -4,7 +4,7 @@ require "trollop"
|
|
4
4
|
require "sumomo"
|
5
5
|
require "yaml"
|
6
6
|
|
7
|
-
SUB_COMMANDS = %w(delete create update)
|
7
|
+
SUB_COMMANDS = %w(delete create update outputs testapi)
|
8
8
|
global_opts = Trollop::options do
|
9
9
|
banner <<-USAGE
|
10
10
|
Sumomo v#{Sumomo::VERSION}
|
@@ -42,6 +42,18 @@ when "outputs"
|
|
42
42
|
puts "Outputs for stack #{ARGV[0]}"
|
43
43
|
puts Sumomo::get_stack_outputs(name: ARGV[0], region: global_opts[:region]).to_yaml
|
44
44
|
|
45
|
+
when "testapi"
|
46
|
+
local_opts = Trollop::options do
|
47
|
+
opt :filename, "File that describes the stack", type: :string, default: "Sumomofile"
|
48
|
+
opt :apiname, "Name of the API you want to test", type: :string
|
49
|
+
opt :prettyprint, "Test API outputs JSON with nice indentation", type: :boolean, default: true
|
50
|
+
end
|
51
|
+
puts "API Test Mode"
|
52
|
+
Sumomo::test_api(local_opts[:apiname], local_opts[:prettyprint]) do
|
53
|
+
proc = Proc.new {}
|
54
|
+
eval File.read(local_opts[:filename]), proc.binding, local_opts[:filename]
|
55
|
+
end
|
56
|
+
exit(0)
|
45
57
|
else
|
46
58
|
Trollop::die "Unknown subcommand #{cmd.inspect}"
|
47
59
|
end
|
data/lib/sumomo.rb
CHANGED
@@ -177,6 +177,50 @@ module Sumomo
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
+
class APITester
|
181
|
+
|
182
|
+
attr_accessor :apis
|
183
|
+
def initialize(&block)
|
184
|
+
@apis = {}
|
185
|
+
instance_eval(&block)
|
186
|
+
end
|
187
|
+
|
188
|
+
def make_api(domain_name, name:, script:nil, dns:nil, cert:nil, &block)
|
189
|
+
@apis[name] = block
|
190
|
+
end
|
191
|
+
|
192
|
+
def method_missing(name, *args, &block)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.test_api(apiname, pretty_print, &block)
|
197
|
+
tester = APITester.new(&block)
|
198
|
+
test_name = nil
|
199
|
+
if tester.apis.length == 1
|
200
|
+
test_name = tester.apis.keys.first
|
201
|
+
elsif apiname
|
202
|
+
if tester.apis.has_key? apiname
|
203
|
+
test_name = apiname
|
204
|
+
else
|
205
|
+
puts "Unknown API name. Please choose from one of the APIs: #{tester.apis.keys.inspect}"
|
206
|
+
end
|
207
|
+
else
|
208
|
+
puts "Please choose from one of the APIs: #{tester.apis.keys.inspect}"
|
209
|
+
end
|
210
|
+
|
211
|
+
if test_name
|
212
|
+
puts "Testing API #{test_name}"
|
213
|
+
apigen = Stack::APIGenerator.new(pretty_print: pretty_print, &tester.apis[test_name])
|
214
|
+
|
215
|
+
script = File.read(File.join(Gem.datadir("sumomo"), "api_modules", "test_script.js"))
|
216
|
+
script.sub!("// {{ ROUTES }}", apigen.generate);
|
217
|
+
|
218
|
+
File.write(".test.js", script)
|
219
|
+
|
220
|
+
exec "NODE_PATH=#{File.join(Gem.datadir("sumomo"), "api_modules", "node_modules")} node .test.js"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
180
224
|
def self.delete_stack(name:, region:, retain_bucket: false)
|
181
225
|
cf = Aws::CloudFormation::Client.new(region: region)
|
182
226
|
ec2 = Aws::EC2::Client.new(region: region)
|
data/lib/sumomo/api.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
module Sumomo
|
3
3
|
module Stack
|
4
4
|
|
5
|
-
|
6
5
|
class APIGenerator
|
7
|
-
def initialize(&block)
|
6
|
+
def initialize(pretty_print: false, &block)
|
8
7
|
@methods = {}
|
8
|
+
@pretty_print = pretty_print
|
9
9
|
instance_eval(&block)
|
10
10
|
end
|
11
11
|
|
@@ -24,6 +24,13 @@ module Sumomo
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def generate
|
27
|
+
|
28
|
+
if @pretty_print
|
29
|
+
pretty_print = ", null, 2"
|
30
|
+
else
|
31
|
+
pretty_print = ""
|
32
|
+
end
|
33
|
+
|
27
34
|
result = ""
|
28
35
|
@methods.each do |path, resource|
|
29
36
|
resource.each do |method, method_info|
|
@@ -46,7 +53,7 @@ module Sumomo
|
|
46
53
|
headers: {
|
47
54
|
"Content-Type" : "application/json; charset=utf-8"
|
48
55
|
},
|
49
|
-
body: JSON.stringify(response_object)
|
56
|
+
body: JSON.stringify(response_object#{pretty_print})
|
50
57
|
};
|
51
58
|
|
52
59
|
callback(null, response);
|
@@ -71,60 +78,7 @@ module Sumomo
|
|
71
78
|
Name name
|
72
79
|
end
|
73
80
|
|
74
|
-
script ||=
|
75
|
-
|
76
|
-
'use strict';
|
77
|
-
console.log('Loading API');
|
78
|
-
|
79
|
-
var os = require('os');
|
80
|
-
var http = require('http');
|
81
|
-
var url = require('url');
|
82
|
-
var merge = require('utils-merge');
|
83
|
-
var Router = require('router')
|
84
|
-
|
85
|
-
var router = Router();
|
86
|
-
|
87
|
-
function prepare(handler)
|
88
|
-
{
|
89
|
-
return function(request, callback)
|
90
|
-
{
|
91
|
-
try
|
92
|
-
{
|
93
|
-
request._native_req.pathParameters = request.params
|
94
|
-
handler(request._native_req, callback);
|
95
|
-
}
|
96
|
-
catch (e)
|
97
|
-
{
|
98
|
-
console.log(e);
|
99
|
-
callback(e, {
|
100
|
-
statusCode: 500,
|
101
|
-
body: JSON.stringify({message: "Internal Server Error"}, null, 2)
|
102
|
-
});
|
103
|
-
}
|
104
|
-
}
|
105
|
-
}
|
106
|
-
|
107
|
-
// {{ ROUTES }}
|
108
|
-
|
109
|
-
exports.handler = function(event, context, callback) {
|
110
|
-
|
111
|
-
var request = {
|
112
|
-
_native_req: event,
|
113
|
-
url: "https://something" + event.path,
|
114
|
-
method: event.httpMethod,
|
115
|
-
params: {}
|
116
|
-
}
|
117
|
-
|
118
|
-
console.log(request);
|
119
|
-
|
120
|
-
router(request, callback, function(err) {
|
121
|
-
callback(null, {
|
122
|
-
statusCode: 404,
|
123
|
-
body: JSON.stringify({message: "File not found"}, null, 2)
|
124
|
-
})
|
125
|
-
});
|
126
|
-
};
|
127
|
-
SCRIPT
|
81
|
+
script ||= File.read(File.join(Gem.datadir("sumomo"), "api_modules", "real_script.js"))
|
128
82
|
|
129
83
|
apigen = APIGenerator.new(&block);
|
130
84
|
script.sub!("// {{ ROUTES }}", apigen.generate);
|
data/lib/sumomo/ecs.rb
CHANGED
@@ -143,6 +143,14 @@ module Sumomo
|
|
143
143
|
Port container_port
|
144
144
|
Protocol "HTTP"
|
145
145
|
VpcId network[:vpc]
|
146
|
+
|
147
|
+
if container[:alb_sticky]
|
148
|
+
TargetGroupAttributes({
|
149
|
+
"stickiness.enabled" => true,
|
150
|
+
"stickiness.type" => "lb_cookie"
|
151
|
+
}.map{|k,v| {Key: k, Value: v} })
|
152
|
+
container.delete(:alb_sticky)
|
153
|
+
end
|
146
154
|
end
|
147
155
|
|
148
156
|
alb_action = {
|
data/lib/sumomo/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sumomo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Siaw
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -2511,6 +2511,8 @@ files:
|
|
2511
2511
|
- data/sumomo/api_modules/node_modules/xmlbuilder/lib/XMLText.js
|
2512
2512
|
- data/sumomo/api_modules/node_modules/xmlbuilder/lib/index.js
|
2513
2513
|
- data/sumomo/api_modules/node_modules/xmlbuilder/package.json
|
2514
|
+
- data/sumomo/api_modules/real_script.js
|
2515
|
+
- data/sumomo/api_modules/test_script.js
|
2514
2516
|
- data/sumomo/custom_resource_utils.js
|
2515
2517
|
- data/sumomo/custom_resources/AMILookup.js
|
2516
2518
|
- data/sumomo/custom_resources/APIDomainName.js
|