swaggerless 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac0529a937e46f94bfb72982270ee109f4f51ed8
4
- data.tar.gz: 56c3a3dd40f15fa239e89a709154356416b773c8
3
+ metadata.gz: d694d07f97c1af61e3c9ae6711123dbf7256d1e4
4
+ data.tar.gz: 9d5618bdf56253b8c8924673ebf9431ede719e8e
5
5
  SHA512:
6
- metadata.gz: f9e344c8fc698771e4fe05c1d078874ae934e1e75f558b6513c3675ebf1fedcaa30098757517e4b2f99f112b71fb0563ce68a6135b30ba1734727d36258dbed7
7
- data.tar.gz: abba001f296c2fab5d1a578c745f7f910812093e8acd2564c1d14afb203242eed001051de5a841c9221c96acd0aa09bf00f0c519e96bab5d3c42af8f9cd13a23
6
+ metadata.gz: f04f394a5a902379f3ed2acf25bbb3d1b6edd8da3dcbabacb9f8f1cb3e8e8fd785457d81d51c6b8138ff6bbc0f111033c2726bdc662f64164bf541388a19d752
7
+ data.tar.gz: 3b76780b95ee2f581b21a4be4953dcea1e8f2ce61724ea32739015f0673e58e7e828942c0715c046c52c51b9b08c5f839d77169bc3f50fcb46d5c1087a5e73e0
@@ -8,8 +8,9 @@ module Swaggerless
8
8
  @env = env
9
9
  @region = region
10
10
  @account = account
11
- @apiGatewayClient = Aws::APIGateway::Client.new(region: @region)
12
- @outputPath = 'output'
11
+ @api_gateway_client = Aws::APIGateway::Client.new(region: @region)
12
+ @output_path = 'output'
13
+ @verbose = false;
13
14
  @function_alias = get_current_package_alias
14
15
  end
15
16
 
@@ -21,40 +22,59 @@ module Swaggerless
21
22
  return swagger["info"]["title"].gsub(/\s+/, '_')
22
23
  end
23
24
 
24
- def update_authorizer_uri(swagger)
25
+ EXT_LAMBDA_NAME = 'x-amazon-lambda-name'
26
+ EXT_LAMBDA_HANDLER = 'x-amazon-lambda-handler'
27
+ EXT_LAMBDA_TIMEOUT = 'x-amazon-lambda-timeout'
28
+ EXT_LAMBDA_RUNTIME = 'x-amazon-lambda-runtime'
29
+
30
+ AMZ_APIGATEWAY_AUTHORIZER = 'x-amazon-apigateway-authorizer'
31
+
32
+ SWGR_OPERATION_ID = 'operationId'
33
+ SWGR_SUMMARY = 'summary'
34
+
35
+ def deploy_authoirizers_and_update_authorizers_uri(lambda_role_arn, swagger)
25
36
  swagger["securityDefinitions"].each do |securityDefinitionName, securityDefinition|
26
- if securityDefinition['x-amazon-apigateway-authorizer'] != nil then
27
- authorizer = securityDefinition['x-amazon-apigateway-authorizer-lambda']
28
- securityDefinition['x-amazon-apigateway-authorizer']["authorizerUri"] = "arn:aws:apigateway:#{@region}:lambda:path/2015-03-31/functions/arn:aws:lambda:#{@region}:#{@account}:function:#{authorizer}/invocations"
29
- lambdaClient = Aws::Lambda::Client.new(region: @region)
37
+ if securityDefinition[AMZ_APIGATEWAY_AUTHORIZER] != nil then
38
+ authorizer = securityDefinition[EXT_LAMBDA_NAME]
39
+ if securityDefinition[EXT_LAMBDA_NAME] then
40
+ securityDefinition[AMZ_APIGATEWAY_AUTHORIZER]["authorizerUri"] = deploy_lambda(lambda_role_arn, securityDefinition[EXT_LAMBDA_NAME],
41
+ "Authorizer for #{swagger["info"]["title"]}", securityDefinition[EXT_LAMBDA_RUNTIME], securityDefinition[EXT_LAMBDA_HANDLER],
42
+ securityDefinition[EXT_LAMBDA_TIMEOUT])
43
+ else
44
+ securityDefinition[AMZ_APIGATEWAY_AUTHORIZER]["authorizerUri"] = "arn:aws:apigateway:#{@region}:lambda:path/2015-03-31/functions/arn:aws:lambda:#{@region}:#{@account}:function:#{authorizer}/invocations"
45
+ end
46
+ lambda_client = Aws::Lambda::Client.new(region: @region)
30
47
  policy_exists = false
31
48
  begin
32
- existing_policies = lambdaClient.get_policy(function_name: authorizer).data
49
+ existing_policies = lambda_client.get_policy(function_name: authorizer).data
33
50
  existing_policy = JSON.parse(existing_policies.policy)
34
51
  policy_exists = existing_policy['Statement'].select { |s| s['Sid'] == "API_2_#{authorizer}" }.any?
35
52
  rescue Aws::Lambda::Errors::ResourceNotFoundException
36
53
  policy_exists = false
37
54
  end
38
55
  unless policy_exists
39
- lambdaClient.add_permission({function_name: "arn:aws:lambda:#{@region}:#{@account}:function:#{authorizer}",
40
- statement_id: "API_2_#{authorizer}", action: "lambda:*", principal: 'apigateway.amazonaws.com'})
56
+ lambda_client.add_permission({function_name: "arn:aws:lambda:#{@region}:#{@account}:function:#{authorizer}",
57
+ statement_id: "API_2_#{authorizer}", action: "lambda:*", principal: 'apigateway.amazonaws.com'})
41
58
  end
42
59
  end
43
60
  end
44
61
  end
45
62
 
46
- def deploy_lambdas_and_update_integration_uris(lambda_role_arn, swagger)
47
- deployedOperations = Hash.new
63
+ def deploy_lambdas_and_update_uris(lambda_role_arn, swagger)
64
+ lambdas_configs = get_lambda_map(swagger)
65
+ deployed_operations = Hash.new
48
66
  swagger["paths"].each do |path, path_config|
49
67
  path_config.each do |method, method_config|
50
- if method_config['operationId'] then
51
- if deployedOperations[method_config['operationId']] == nil then
52
- function_name = Deployer.get_service_prefix(swagger) + "_" + method_config['operationId'].split(".").last
53
- deployedOperations[method_config['operationId']] =
54
- deploy_lambda(lambda_role_arn, function_name, method_config["summary"], method_config['x-amazon-lambda-runtime'] || 'nodejs4.3',
55
- method_config['operationId'], method_config['x-amazon-lambda-timeout'] || 5)
68
+ if method_config[SWGR_OPERATION_ID] or method_config[EXT_LAMBDA_HANDLER] then
69
+ if deployed_operations[method_config[EXT_LAMBDA_NAME]] == nil
70
+ config = lambdas_configs[method_config[EXT_LAMBDA_NAME]]
71
+ deployed_operations[method_config[EXT_LAMBDA_NAME]] = deploy_lambda(lambda_role_arn, method_config[EXT_LAMBDA_NAME], config[:description],
72
+ config[:runtime], config[:handler], config[:timeout])
56
73
  end
57
- method_config['x-amazon-apigateway-integration']['uri'] = deployedOperations[method_config['operationId']]
74
+ puts "Updating swagger with integration uri for #{method} #{path}: #{deployed_operations[method_config[EXT_LAMBDA_NAME]]}" unless not @verbose
75
+ method_config['x-amazon-apigateway-integration']['uri'] = deployed_operations[method_config[EXT_LAMBDA_NAME]]
76
+ elsif method_config[EXT_LAMBDA_NAME] then
77
+ method_config['x-amazon-apigateway-integration']['uri'] = "arn:aws:apigateway:#{@region}:lambda:path/2015-03-31/functions/arn:aws:lambda:#{@region}:#{@account}:function:#{method_config[EXT_LAMBDA_NAME]}/invocations"
58
78
  end
59
79
  end
60
80
  end
@@ -62,46 +82,48 @@ module Swaggerless
62
82
 
63
83
  def deploy_lambda(lambda_role_arn, function_name, summary, runtime, handler, timeout)
64
84
  puts "Deploying #{function_name}"
65
- lambdaClient = Aws::Lambda::Client.new(region: @region)
85
+ runtime ||= 'nodejs4.3'
86
+ timeout ||= 5
87
+ lambda_client = Aws::Lambda::Client.new(region: @region)
66
88
  begin
67
- lambdaClient.get_alias({function_name: function_name, name: @function_alias})
89
+ lambda_client.get_alias({function_name: function_name, name: @function_alias})
68
90
  rescue Aws::Lambda::Errors::ResourceNotFoundException
69
- lambdaResponse = nil
70
- zipFileContent = File.read(File.join(@outputPath,"#{@function_alias}.zip"))
91
+ lambda_response = nil
92
+ zip_file_content = File.read(File.join(@output_path, "#{@function_alias}.zip"))
71
93
  begin
72
- lambdaClient.get_function({function_name: function_name})
73
- lambdaResponse = lambdaClient.update_function_code({function_name: function_name, zip_file: zipFileContent, publish: true})
74
- lambdaClient.update_function_configuration({function_name: function_name, runtime: runtime, role: lambda_role_arn, handler: handler, description: summary, timeout: timeout})
94
+ lambda_client.get_function({function_name: function_name})
95
+ lambda_response = lambda_client.update_function_code({function_name: function_name, zip_file: zip_file_content, publish: true})
96
+ lambda_client.update_function_configuration({function_name: function_name, runtime: runtime, role: lambda_role_arn, handler: handler, description: summary, timeout: timeout})
75
97
  rescue Aws::Lambda::Errors::ResourceNotFoundException
76
98
  puts "Creating new function #{function_name}"
77
- lambdaResponse = lambdaClient.create_function({function_name: function_name, runtime: runtime, role: lambda_role_arn, handler: handler, code: { zip_file: zipFileContent }, description: summary, publish: true, timeout: timeout})
99
+ lambda_response = lambda_client.create_function({function_name: function_name, runtime: runtime, role: lambda_role_arn, handler: handler, code: {zip_file: zip_file_content }, description: summary, publish: true, timeout: timeout})
78
100
  end
79
101
  puts "Creating alias #{@function_alias}"
80
- aliasResp = lambdaClient.create_alias({function_name: function_name, name: @function_alias, function_version: lambdaResponse.version, description: "Deployment of new version on " + Time.now.inspect})
81
- lambdaClient.add_permission({function_name: aliasResp.alias_arn, statement_id: "API_2_#{function_name}_#{@function_alias}", action: "lambda:*", principal: 'apigateway.amazonaws.com'})
102
+ alias_resp = lambda_client.create_alias({function_name: function_name, name: @function_alias, function_version: lambda_response.version, description: "Deployment of new version on " + Time.now.inspect})
103
+ lambda_client.add_permission({function_name: alias_resp.alias_arn, statement_id: "API_2_#{function_name}_#{@function_alias}", action: "lambda:*", principal: 'apigateway.amazonaws.com'})
82
104
  end
83
105
  return "arn:aws:apigateway:#{@region}:lambda:path/2015-03-31/functions/arn:aws:lambda:#{@region}:#{@account}:function:#{function_name}:#{@function_alias}/invocations"
84
106
  end
85
107
 
86
108
  def get_current_package_alias
87
- zipFiles = Dir["#{@outputPath}/*.zip"]
109
+ zipFiles = Dir["#{@output_path}/*.zip"]
88
110
  if zipFiles.length == 0 then
89
111
  raise 'No package in the output folder. Unable to continue.'
90
112
  elsif zipFiles.length == 0
91
113
  raise 'Multiple package in the output folder. Unable to continue.'
92
114
  end
93
- return File.basename(zipFiles.first, '.zip')
115
+ File.basename(zipFiles.first, '.zip')
94
116
  end
95
117
 
96
118
  def create_api_gateway(swagger)
97
119
  puts "Creating API Gateway"
98
- apis = @apiGatewayClient.get_rest_apis(limit: 500).data
120
+ apis = @api_gateway_client.get_rest_apis(limit: 500).data
99
121
  api = apis.items.select { |a| a.name == swagger['info']['title'] }.first
100
122
 
101
123
  if api then
102
- resp = @apiGatewayClient.put_rest_api({rest_api_id: api.id, mode: "overwrite", fail_on_warnings: true, body: swagger.to_yaml})
124
+ resp = @api_gateway_client.put_rest_api({rest_api_id: api.id, mode: "overwrite", fail_on_warnings: true, body: swagger.to_yaml})
103
125
  else
104
- resp = @apiGatewayClient.import_rest_api({fail_on_warnings: true, body: swagger.to_yaml})
126
+ resp = @api_gateway_client.import_rest_api({fail_on_warnings: true, body: swagger.to_yaml})
105
127
  end
106
128
 
107
129
  if resp.warnings then
@@ -114,14 +136,16 @@ module Swaggerless
114
136
  end
115
137
 
116
138
  def create_api_gateway_deployment(lambda_role_arn, swagger)
117
- deploy_lambdas_and_update_integration_uris(lambda_role_arn, swagger)
118
- update_authorizer_uri(swagger)
119
- apiId = self.create_api_gateway(swagger);
139
+ deploy_lambdas_and_update_uris(lambda_role_arn, swagger)
140
+ deploy_authoirizers_and_update_authorizers_uri(lambda_role_arn, swagger)
141
+ api_id = self.create_api_gateway(swagger);
120
142
  while true do
121
143
  begin
122
144
  puts "Creating API Gateway Deployment"
123
- @apiGatewayClient.create_deployment({rest_api_id: apiId, stage_name: @env, description: "Automated deployment of #{@env}", variables: { "env" => @env }});
124
- break
145
+ @api_gateway_client.create_deployment({rest_api_id: api_id, stage_name: @env, description: "Automated deployment of #{@env}", variables: {"env" => @env }});
146
+ url = "https://#{api_id}.execute-api.#{@region}.amazonaws.com/#{@env}/"
147
+ puts "API available at #{url}"
148
+ return url;
125
149
  rescue Aws::APIGateway::Errors::TooManyRequestsException => e
126
150
  STDERR.puts 'WARNING: Got TooManyRequests response from API Gateway. Waiting for a second.'
127
151
  sleep(1)
@@ -130,6 +154,55 @@ module Swaggerless
130
154
 
131
155
  end
132
156
 
157
+ private
158
+
159
+ def get_lambda_map(swagger)
160
+ lambdas_map = Hash.new
161
+ swagger["paths"].each do |path, path_config|
162
+ path_config.each do |method, method_config|
163
+ if lambdas_map[method_config[EXT_LAMBDA_NAME]] then
164
+ stored_version = lambdas_map[method_config[EXT_LAMBDA_NAME]];
165
+ encountered_version = build_lambda_config_hash(method_config)
166
+ unless is_lambda_config_correct(stored_version, encountered_version) then
167
+ raise "Lambda #{method_config[EXT_LAMBDA_NAME]} mentioned multiple times in configuration with different settings"
168
+ end
169
+ lambdas_map[method_config[EXT_LAMBDA_NAME]]['description'] = 'Part of ' + Deployer.get_service_prefix(swagger)
170
+ else
171
+ lambdas_map[method_config[EXT_LAMBDA_NAME]] = build_lambda_config_hash(method_config)
172
+ end
173
+ end
174
+ end
175
+
176
+ swagger["securityDefinitions"].each do |securityDefinitionName, securityDefinition|
177
+ if securityDefinition[AMZ_APIGATEWAY_AUTHORIZER] != nil then
178
+ if lambdas_map[securityDefinition[EXT_LAMBDA_NAME]] then
179
+ stored_version = lambdas_map[securityDefinition[AMZ_APIGATEWAY_AUTHORIZER][EXT_LAMBDA_NAME]];
180
+ encountered_version = build_lambda_config_hash(securityDefinition[AMZ_APIGATEWAY_AUTHORIZER])
181
+ unless is_lambda_config_correct(stored_version, encountered_version)
182
+ raise "Lambda #{method_config[EXT_LAMBDA_NAME]} mentioned multiple times in configuration with different settings"
183
+ end
184
+ lambdas_map[securityDefinition[EXT_LAMBDA_NAME]].description = 'Part of ' + Deployer.get_service_prefix(swagger)
185
+ else
186
+ lambdas_map[securityDefinition[EXT_LAMBDA_NAME]] = build_lambda_config_hash(securityDefinition)
187
+ end
188
+ end
189
+ end
190
+ return lambdas_map
191
+ end
192
+
193
+ def is_lambda_config_correct(l1, l2)
194
+ return (l1['handler'] == l2['handler'] and
195
+ l1['timeout'] == l2['timeout'] and
196
+ l1['runtime'] == l2['runtime'])
197
+ end
198
+
199
+ def build_lambda_config_hash(method_config)
200
+ { handler: method_config[EXT_LAMBDA_HANDLER],
201
+ timeout: method_config[EXT_LAMBDA_TIMEOUT],
202
+ runtime: method_config[EXT_LAMBDA_RUNTIME],
203
+ description: method_config[SWGR_SUMMARY]}
204
+ end
205
+
133
206
  end
134
207
 
135
208
  end
@@ -1,3 +1,3 @@
1
1
  module Swaggerless
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -3,50 +3,55 @@ require "json"
3
3
  require "swaggerless"
4
4
  require 'fileutils'
5
5
 
6
- desc 'Deploys to an environment specified as parameter'
7
- task :deploy, [ :environment ] => [ :clean, :package ] do |t, args|
8
- puts "Deploying API Gateway"
9
- if not @swaggerSpecFile then
10
- @swaggerSpecFile = 'swagger.yaml'
11
- STDERR.puts("Swagger file not configured. Trying default ('#{@swaggerSpecFile}'). Set @swaggerSpecFile to point to swagger yaml file if you use different file name")
6
+ namespace :swaggerless do
7
+
8
+ desc 'Deploys to an environment specified as parameter'
9
+ task :deploy, [ :environment ] => [ :clean, :package ] do |t, args|
10
+ puts "Deploying API Gateway"
11
+ if not @swaggerSpecFile then
12
+ @swaggerSpecFile = 'swagger.yaml'
13
+ STDERR.puts("Swagger file not configured. Trying default ('#{@swaggerSpecFile}'). Set @swaggerSpecFile to point to swagger yaml file if you use different file name")
14
+ end
15
+
16
+ if not @lambdaRoleArn then
17
+ raise "Unable to continue. Please configue @lambdaRoleArn in the Rakefile"
18
+ end
19
+
20
+ if not @awsRegion then
21
+ @awsRegion = ENV['AWS_REGION'] || 'eu-west-1'
22
+ STDERR.puts("AWS Region is not configured. Trying default ('#{@awsRegion}'). Set @awsRegion to point to swagger yaml file if you use different file name")
23
+ end
24
+
25
+ if not @awsAccount then
26
+ raise "Unable to continue. Please configue @awsAccount in the Rakefile"
27
+ end
28
+
29
+ swagger_content = File.read(@swaggerSpecFile)
30
+ swagger = YAML.load(swagger_content)
31
+ ENV["apiUrl"] = Swaggerless::Deployer.new(@awsAccount, @awsRegion, args[:environment].gsub(/[^a-zA-Z0-9_]/, "_")).create_api_gateway_deployment(@lambdaRoleArn, swagger)
32
+ puts "Setting $apiUrl environment variable to point to the deployed API"
12
33
  end
13
34
 
14
- if not @lambdaRoleArn then
15
- raise "Unable to continue. Please configue @lambdaRoleArn in the Rakefile"
16
- end
17
-
18
- if not @awsRegion then
19
- @awsRegion = ENV['AWS_REGION'] || 'eu-west-1'
20
- STDERR.puts("AWS Region is not configured. Trying default ('#{@awsRegion}'). Set @awsRegion to point to swagger yaml file if you use different file name")
21
- end
35
+ desc 'Package the project for AWS Lambda'
36
+ task :package do
37
+ puts "Packaging"
22
38
 
23
- if not @awsAccount then
24
- raise "Unable to continue. Please configue @awsAccount in the Rakefile"
25
- end
39
+ FileUtils.mkdir_p 'output'
26
40
 
27
- swagger_content = File.read(@swaggerSpecFile)
28
- swagger = YAML.load(swagger_content)
29
- Swaggerless::Deployer.new(@awsAccount, @awsRegion, args[:environment].gsub(/[^a-zA-Z0-9_]/, "_")).create_api_gateway_deployment(@lambdaRoleArn, swagger)
30
- end
41
+ if not @packageDir then
42
+ @packageDir = 'src'
43
+ STDERR.puts("Package directory not configured. Trying default ('#{@packageDir}'). Set @packageDir to point to the directory that should be packaged for AWS Lambda")
44
+ end
31
45
 
32
- desc 'Package the project for AWS Lambda'
33
- task :package do
34
- puts "Packaging"
35
-
36
- FileUtils.mkdir_p 'output'
37
-
38
- if not @packageDir then
39
- @packageDir = 'src'
40
- STDERR.puts("Package directory not configured. Trying default ('#{@packageDir}'). Set @packageDir to point to the directory that should be packaged for AWS Lambda")
46
+ swagger_content = File.read(@swaggerSpecFile)
47
+ swagger = YAML.load(swagger_content)
48
+ servicePrefix = Swaggerless::Deployer.get_service_prefix(swagger)
49
+ Swaggerless::Packager.new(@packageDir, "output/#{servicePrefix}").write
41
50
  end
42
51
 
43
- swagger_content = File.read(@swaggerSpecFile)
44
- swagger = YAML.load(swagger_content)
45
- servicePrefix = Swaggerless::Deployer.get_service_prefix(swagger)
46
- Swaggerless::Packager.new(@packageDir, "output/#{servicePrefix}").write
47
- end
52
+ desc 'Clean'
53
+ task :clean do
54
+ FileUtils.rm_rf('output')
55
+ end
48
56
 
49
- desc 'Clean'
50
- task :clean do
51
- FileUtils.rm_rf('output')
52
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swaggerless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafal Nowosielski
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-25 00:00:00.000000000 Z
11
+ date: 2016-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler