sumomo 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|