cfn-vpn 0.5.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build-gem.yml +25 -0
  3. data/.github/workflows/release-gem.yml +31 -0
  4. data/.github/workflows/release-image.yml +33 -0
  5. data/Gemfile.lock +30 -38
  6. data/README.md +1 -247
  7. data/cfn-vpn.gemspec +3 -2
  8. data/docs/README.md +44 -0
  9. data/docs/certificate-users.md +89 -0
  10. data/docs/getting-started.md +87 -0
  11. data/docs/modifying.md +67 -0
  12. data/docs/routes.md +82 -0
  13. data/docs/scheduling.md +32 -0
  14. data/docs/sessions.md +27 -0
  15. data/lib/cfnvpn.rb +31 -27
  16. data/lib/cfnvpn/{client.rb → actions/client.rb} +5 -6
  17. data/lib/cfnvpn/{embedded.rb → actions/embedded.rb} +15 -15
  18. data/lib/cfnvpn/actions/init.rb +130 -0
  19. data/lib/cfnvpn/actions/modify.rb +149 -0
  20. data/lib/cfnvpn/actions/params.rb +73 -0
  21. data/lib/cfnvpn/{revoke.rb → actions/revoke.rb} +6 -6
  22. data/lib/cfnvpn/actions/routes.rb +144 -0
  23. data/lib/cfnvpn/{sessions.rb → actions/sessions.rb} +5 -5
  24. data/lib/cfnvpn/{share.rb → actions/share.rb} +10 -10
  25. data/lib/cfnvpn/actions/subnets.rb +78 -0
  26. data/lib/cfnvpn/certificates.rb +5 -5
  27. data/lib/cfnvpn/clientvpn.rb +34 -68
  28. data/lib/cfnvpn/compiler.rb +23 -0
  29. data/lib/cfnvpn/config.rb +34 -78
  30. data/lib/cfnvpn/{cloudformation.rb → deployer.rb} +47 -19
  31. data/lib/cfnvpn/log.rb +26 -26
  32. data/lib/cfnvpn/s3.rb +4 -4
  33. data/lib/cfnvpn/string.rb +29 -0
  34. data/lib/cfnvpn/templates/helper.rb +14 -0
  35. data/lib/cfnvpn/templates/vpn.rb +344 -0
  36. data/lib/cfnvpn/version.rb +1 -1
  37. metadata +55 -22
  38. data/lib/cfnvpn/cfhighlander.rb +0 -49
  39. data/lib/cfnvpn/init.rb +0 -109
  40. data/lib/cfnvpn/modify.rb +0 -103
  41. data/lib/cfnvpn/routes.rb +0 -84
  42. data/lib/cfnvpn/templates/cfnvpn.cfhighlander.rb.tt +0 -27
data/lib/cfnvpn/s3.rb CHANGED
@@ -14,7 +14,7 @@ module CfnVpn
14
14
  def store_object(file)
15
15
  body = File.open(file, 'rb').read
16
16
  file_name = file.split('/').last
17
- Log.logger.debug("uploading #{file} to s3://#{@bucket}/#{@path}/#{file_name}")
17
+ CfnVpn::Log.logger.debug("uploading #{file} to s3://#{@bucket}/#{@path}/#{file_name}")
18
18
  @client.put_object({
19
19
  body: body,
20
20
  bucket: @bucket,
@@ -26,7 +26,7 @@ module CfnVpn
26
26
 
27
27
  def get_object(file)
28
28
  file_name = file.split('/').last
29
- Log.logger.debug("downloading s3://#{@bucket}/#{@path}/#{file_name} to #{file}")
29
+ CfnVpn::Log.logger.debug("downloading s3://#{@bucket}/#{@path}/#{file_name} to #{file}")
30
30
  @client.get_object(
31
31
  response_target: file,
32
32
  bucket: @bucket,
@@ -34,7 +34,7 @@ module CfnVpn
34
34
  end
35
35
 
36
36
  def store_config(config)
37
- Log.logger.debug("uploading config to s3://#{@bucket}/#{@path}/#{@name}.config.ovpn")
37
+ CfnVpn::Log.logger.debug("uploading config to s3://#{@bucket}/#{@path}/#{@name}.config.ovpn")
38
38
  @client.put_object({
39
39
  body: config,
40
40
  bucket: @bucket,
@@ -54,7 +54,7 @@ module CfnVpn
54
54
  end
55
55
 
56
56
  def store_embedded_config(config, cn)
57
- Log.logger.debug("uploading config to s3://#{@bucket}/#{@path}/#{@name}_#{cn}.config.ovpn")
57
+ CfnVpn::Log.logger.debug("uploading config to s3://#{@bucket}/#{@path}/#{@name}_#{cn}.config.ovpn")
58
58
  @client.put_object({
59
59
  body: config,
60
60
  bucket: @bucket,
@@ -0,0 +1,29 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+
10
+ def resource_safe
11
+ self.gsub(/[^a-zA-Z0-9]/, "").capitalize
12
+ end
13
+
14
+ def colorize(color_code)
15
+ "\e[#{color_code}m#{self}\e[0m"
16
+ end
17
+
18
+ def red
19
+ colorize(31)
20
+ end
21
+
22
+ def green
23
+ colorize(32)
24
+ end
25
+
26
+ def yellow
27
+ colorize(33)
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ require 'aws-sdk-ec2'
2
+
3
+ module CfnVpn
4
+ module Templates
5
+ class Helper
6
+ def self.get_auth_cidr(region, subnet_id)
7
+ client = Aws::EC2::Client.new(region: region)
8
+ subnets = client.describe_subnets({subnet_ids:[subnet_id]})
9
+ vpcs = client.describe_vpcs({vpc_ids:[subnets.subnets[0].vpc_id]})
10
+ return vpcs.vpcs[0].cidr_block
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,344 @@
1
+ require 'cfndsl'
2
+ require 'cfnvpn/templates/helper'
3
+
4
+ module CfnVpn
5
+ module Templates
6
+ class Vpn < CfnDsl::CloudFormationTemplate
7
+
8
+ def initialize
9
+ super
10
+ end
11
+
12
+ def render(name, config)
13
+ Description "cfnvpn #{name} AWS Client-VPN"
14
+ Parameter(:AssociateSubnets) {
15
+ Type 'String'
16
+ Default 'true'
17
+ AllowedValues ['true', 'false']
18
+ Description 'Toggle to false to disassociate all Client VPN subnet associations'
19
+ }
20
+
21
+ Condition(:EnableSubnetAssociation, FnEquals(Ref(:AssociateSubnets), 'true'))
22
+
23
+ Logs_LogGroup(:ClientVpnLogGroup) {
24
+ LogGroupName FnSub("#{name}-ClientVpn")
25
+ RetentionInDays 30
26
+ }
27
+
28
+ EC2_ClientVpnEndpoint(:ClientVpnEndpoint) {
29
+ Description FnSub("cfnvpn #{name} AWS Client-VPN")
30
+ AuthenticationOptions([
31
+ if config[:type] == 'federated'
32
+ {
33
+ FederatedAuthentication: {
34
+ SAMLProviderArn: config[:saml_arn],
35
+ SelfServiceSAMLProviderArn: config[:saml_arn]
36
+ },
37
+ Type: 'federated-authentication'
38
+ }
39
+ else
40
+ {
41
+ MutualAuthentication: {
42
+ ClientRootCertificateChainArn: config[:client_cert_arn]
43
+ },
44
+ Type: 'certificate-authentication'
45
+ }
46
+ end
47
+ ])
48
+ ServerCertificateArn config[:server_cert_arn]
49
+ ClientCidrBlock config[:cidr]
50
+ ConnectionLogOptions({
51
+ CloudwatchLogGroup: Ref(:ClientVpnLogGroup),
52
+ Enabled: true
53
+ })
54
+ DnsServers config[:dns_servers].any? ? config[:dns_servers] : Ref('AWS::NoValue')
55
+ TagSpecifications([{
56
+ ResourceType: "client-vpn-endpoint",
57
+ Tags: [
58
+ { Key: 'Name', Value: name }
59
+ ]
60
+ }])
61
+ TransportProtocol config[:protocol]
62
+ SplitTunnel config[:split_tunnel]
63
+ }
64
+
65
+ config[:subnet_ids].each_with_index do |subnet, index|
66
+ suffix = index == 0 ? "" : "For#{subnet.resource_safe}"
67
+
68
+ EC2_ClientVpnTargetNetworkAssociation(:"ClientVpnTargetNetworkAssociation#{suffix}") {
69
+ Condition(:EnableSubnetAssociation)
70
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
71
+ SubnetId subnet
72
+ }
73
+
74
+ if config[:default_groups].any?
75
+ config[:default_groups].each do |group|
76
+ EC2_ClientVpnAuthorizationRule(:"TargetNetworkAuthorizationRule#{suffix}#{group.resource_safe}"[0..255]) {
77
+ Condition(:EnableSubnetAssociation)
78
+ DependsOn "ClientVpnTargetNetworkAssociation#{suffix}"
79
+ Description FnSub("#{name} client-vpn auth rule for subnet association")
80
+ AccessGroupId group
81
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
82
+ TargetNetworkCidr CfnVpn::Templates::Helper.get_auth_cidr(config[:region], subnet)
83
+ }
84
+ end
85
+ else
86
+ EC2_ClientVpnAuthorizationRule(:"TargetNetworkAuthorizationRule#{suffix}") {
87
+ Condition(:EnableSubnetAssociation)
88
+ DependsOn "ClientVpnTargetNetworkAssociation#{suffix}"
89
+ Description FnSub("#{name} client-vpn auth rule for subnet association")
90
+ AuthorizeAllGroups true
91
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
92
+ TargetNetworkCidr CfnVpn::Templates::Helper.get_auth_cidr(config[:region], subnet)
93
+ }
94
+ end
95
+
96
+ if subnet == config[:internet_route]
97
+ EC2_ClientVpnRoute(:RouteToInternet) {
98
+ Condition(:EnableSubnetAssociation)
99
+ DependsOn "ClientVpnTargetNetworkAssociation#{suffix}"
100
+ Description 'Route to the internet'
101
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
102
+ DestinationCidrBlock '0.0.0.0/0'
103
+ TargetVpcSubnetId config[:internet_route]
104
+ }
105
+
106
+ EC2_ClientVpnAuthorizationRule(:RouteToInternetAuthorizationRule) {
107
+ Condition(:EnableSubnetAssociation)
108
+ DependsOn "ClientVpnTargetNetworkAssociation#{suffix}"
109
+ Description 'Route to the internet'
110
+ AuthorizeAllGroups true
111
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
112
+ TargetNetworkCidr '0.0.0.0/0'
113
+ }
114
+
115
+ output(:InternetRoute, config[:internet_route])
116
+ end
117
+ end
118
+
119
+ config[:routes].each do |route|
120
+ EC2_ClientVpnRoute(:"#{route[:cidr].resource_safe}VpnRoute") {
121
+ Description route[:desc]
122
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
123
+ DestinationCidrBlock route[:cidr]
124
+ TargetVpcSubnetId route[:subnet]
125
+ }
126
+ if route[:groups].any?
127
+ route[:groups].each do |group|
128
+ EC2_ClientVpnAuthorizationRule(:"#{route[:cidr].resource_safe}AuthorizationRule#{group.resource_safe}"[0..255]) {
129
+ Description route[:desc]
130
+ AccessGroupId group
131
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
132
+ TargetNetworkCidr route[:cidr]
133
+ }
134
+ end
135
+ else
136
+ EC2_ClientVpnAuthorizationRule(:"#{route[:cidr].resource_safe}AllowAllAuthorizationRule") {
137
+ Description route[:desc]
138
+ AuthorizeAllGroups true
139
+ ClientVpnEndpointId Ref(:ClientVpnEndpoint)
140
+ TargetNetworkCidr route[:cidr]
141
+ }
142
+ end
143
+ end
144
+
145
+ SSM_Parameter(:CfnVpnConfig) {
146
+ Description "#{name} cfnvpn config"
147
+ Name "/cfnvpn/config/#{name}"
148
+ Tier 'Standard'
149
+ Type 'String'
150
+ Value config.to_json
151
+ Tags({
152
+ Name: "#{name}-cfnvpn-config",
153
+ Environment: 'cfnvpn'
154
+ })
155
+ }
156
+
157
+ if config[:start] || config[:stop]
158
+ scheduler(name, config[:start], config[:stop])
159
+ output(:Start, config[:start]) if config[:start]
160
+ output(:Stop, config[:stop]) if config[:stop]
161
+ end
162
+
163
+ output(:ServerCertArn, config[:server_cert_arn])
164
+ output(:Cidr, config[:cidr])
165
+ output(:DnsServers, config.fetch(:dns_servers, []).join(','))
166
+ output(:SubnetIds, config[:subnet_ids].join(','))
167
+ output(:SplitTunnel, config[:split_tunnel])
168
+ output(:Protocol, config[:protocol])
169
+ output(:Type, config[:type])
170
+
171
+ if config[:type] == 'federated'
172
+ output(:SamlArn, config[:saml_arn])
173
+ else
174
+ output(:ClientCertArn, config[:client_cert_arn])
175
+ end
176
+ end
177
+
178
+ def output(name, value)
179
+ Output(name) { Value value }
180
+ end
181
+
182
+ def scheduler(name, start, stop)
183
+ IAM_Role(:ClientVpnSchedulerRole) {
184
+ AssumeRolePolicyDocument({
185
+ Version: '2012-10-17',
186
+ Statement: [{
187
+ Effect: 'Allow',
188
+ Principal: { Service: [ 'lambda.amazonaws.com' ] },
189
+ Action: [ 'sts:AssumeRole' ]
190
+ }]
191
+ })
192
+ Path '/cfnvpn/'
193
+ Policies([
194
+ {
195
+ PolicyName: 'cloudformation',
196
+ PolicyDocument: {
197
+ Version: '2012-10-17',
198
+ Statement: [{
199
+ Effect: 'Allow',
200
+ Action: [
201
+ 'cloudformation:UpdateStack'
202
+ ],
203
+ Resource: FnSub("arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/#{name}-cfnvpn/*")
204
+ }]
205
+ }
206
+ },
207
+ {
208
+ PolicyName: 'client-vpn',
209
+ PolicyDocument: {
210
+ Version: '2012-10-17',
211
+ Statement: [{
212
+ Effect: 'Allow',
213
+ Action: [
214
+ 'ec2:AssociateClientVpnTargetNetwork',
215
+ 'ec2:DisassociateClientVpnTargetNetwork',
216
+ 'ec2:DescribeClientVpnTargetNetworks',
217
+ 'ec2:AuthorizeClientVpnIngress',
218
+ 'ec2:RevokeClientVpnIngress',
219
+ 'ec2:DescribeClientVpnAuthorizationRules',
220
+ 'ec2:DescribeClientVpnEndpoints',
221
+ 'ec2:DescribeClientVpnConnections',
222
+ 'ec2:TerminateClientVpnConnections'
223
+ ],
224
+ Resource: '*'
225
+ }]
226
+ }
227
+ },
228
+ {
229
+ PolicyName: 'logging',
230
+ PolicyDocument: {
231
+ Version: '2012-10-17',
232
+ Statement: [{
233
+ Effect: 'Allow',
234
+ Action: [
235
+ 'logs:DescribeLogGroups',
236
+ 'logs:CreateLogGroup',
237
+ 'logs:CreateLogStream',
238
+ 'logs:DescribeLogStreams',
239
+ 'logs:PutLogEvents'
240
+ ],
241
+ Resource: '*'
242
+ }]
243
+ }
244
+ }
245
+ ])
246
+ Tags([
247
+ { Key: 'Name', Value: "#{name}-cfnvpn-scheduler-role" },
248
+ { Key: 'Environment', Value: 'cfnvpn' }
249
+ ])
250
+ }
251
+
252
+ Lambda_Function(:ClientVpnSchedulerFunction) {
253
+ Runtime 'python3.7'
254
+ Role FnGetAtt(:ClientVpnSchedulerRole, :Arn)
255
+ MemorySize '128'
256
+ Handler 'index.handler'
257
+ Code({
258
+ ZipFile: <<~EOS
259
+ import boto3
260
+
261
+ def handler(event, context):
262
+
263
+ print(f"updating cfn-vpn stack {event['StackName']} parameter AssociateSubnets with value {event['AssociateSubnets']}")
264
+
265
+ if event['AssociateSubnets'] == 'false':
266
+ print(f"terminating current vpn sessions to {event['ClientVpnEndpointId']}")
267
+ ec2 = boto3.client('ec2')
268
+ resp = ec2.describe_client_vpn_connections(ClientVpnEndpointId=event['ClientVpnEndpointId'])
269
+ for conn in resp['Connections']:
270
+ if conn['Status']['Code'] == 'active':
271
+ ec2.terminate_client_vpn_connections(
272
+ ClientVpnEndpointId=event['ClientVpnEndpointId'],
273
+ ConnectionId=conn['ConnectionId']
274
+ )
275
+ print(f"terminated session {conn['ConnectionId']}")
276
+
277
+ client = boto3.client('cloudformation')
278
+ print(client.update_stack(
279
+ StackName=event['StackName'],
280
+ UsePreviousTemplate=True,
281
+ Capabilities=['CAPABILITY_IAM'],
282
+ Parameters=[
283
+ {
284
+ 'ParameterKey': 'AssociateSubnets',
285
+ 'ParameterValue': event['AssociateSubnets']
286
+ }
287
+ ]
288
+ ))
289
+
290
+ return 'OK'
291
+ EOS
292
+ })
293
+ Tags([
294
+ { Key: 'Name', Value: "#{name}-cfnvpn-scheduler-function" },
295
+ { Key: 'Environment', Value: 'cfnvpn' }
296
+ ])
297
+ }
298
+
299
+ Logs_LogGroup(:ClientVpnSchedulerLogGroup) {
300
+ LogGroupName FnSub("/aws/lambda/${ClientVpnSchedulerFunction}")
301
+ RetentionInDays 30
302
+ }
303
+
304
+ Lambda_Permission(:ClientVpnSchedulerFunctionPermissions) {
305
+ FunctionName Ref(:ClientVpnSchedulerFunction)
306
+ Action 'lambda:InvokeFunction'
307
+ Principal 'events.amazonaws.com'
308
+ }
309
+
310
+ if start
311
+ Events_Rule(:ClientVpnSchedulerStart) {
312
+ State 'ENABLED'
313
+ Description "cfnvpn start schedule"
314
+ ScheduleExpression "cron(#{start})"
315
+ Targets([
316
+ {
317
+ Arn: FnGetAtt(:ClientVpnSchedulerFunction, :Arn),
318
+ Id: 'cfnvpnschedulerstart',
319
+ Input: FnSub({ StackName: "#{name}-cfnvpn", AssociateSubnets: 'true', ClientVpnEndpointId: "${ClientVpnEndpoint}" }.to_json)
320
+ }
321
+ ])
322
+ }
323
+ end
324
+
325
+ if stop
326
+ Events_Rule(:ClientVpnSchedulerStop) {
327
+ State 'ENABLED'
328
+ Description "cfnvpn stop schedule"
329
+ ScheduleExpression "cron(#{stop})"
330
+ Targets([
331
+ {
332
+ Arn: FnGetAtt(:ClientVpnSchedulerFunction, :Arn),
333
+ Id: 'cfnvpnschedulerstop',
334
+ Input: FnSub({ StackName: "#{name}-cfnvpn", AssociateSubnets: 'false', ClientVpnEndpointId: "${ClientVpnEndpoint}" }.to_json)
335
+ }
336
+ ])
337
+ }
338
+ end
339
+
340
+ end
341
+
342
+ end
343
+ end
344
+ end
@@ -1,4 +1,4 @@
1
1
  module CfnVpn
2
- VERSION = "0.5.1".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  CHANGE_SET_VERSION = VERSION.gsub('.', '-').freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn-vpn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guslington
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-18 00:00:00.000000000 Z
11
+ date: 2021-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -45,25 +45,25 @@ dependencies:
45
45
  - !ruby/object:Gem::Version
46
46
  version: '2'
47
47
  - !ruby/object:Gem::Dependency
48
- name: cfhighlander
48
+ name: cfndsl
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.9'
53
+ version: '1'
54
54
  - - "<"
55
55
  - !ruby/object:Gem::Version
56
- version: '1'
56
+ version: '2'
57
57
  type: :runtime
58
58
  prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: '0.9'
63
+ version: '1'
64
64
  - - "<"
65
65
  - !ruby/object:Gem::Version
66
- version: '1'
66
+ version: '2'
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: netaddr
69
69
  requirement: !ruby/object:Gem::Requirement
@@ -158,6 +158,26 @@ dependencies:
158
158
  - - "<"
159
159
  - !ruby/object:Gem::Version
160
160
  version: '2'
161
+ - !ruby/object:Gem::Dependency
162
+ name: aws-sdk-ssm
163
+ requirement: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: '1'
168
+ - - "<"
169
+ - !ruby/object:Gem::Version
170
+ version: '2'
171
+ type: :runtime
172
+ prerelease: false
173
+ version_requirements: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - "~>"
176
+ - !ruby/object:Gem::Version
177
+ version: '1'
178
+ - - "<"
179
+ - !ruby/object:Gem::Version
180
+ version: '2'
161
181
  - !ruby/object:Gem::Dependency
162
182
  name: bundler
163
183
  requirement: !ruby/object:Gem::Requirement
@@ -178,14 +198,14 @@ dependencies:
178
198
  requirements:
179
199
  - - "~>"
180
200
  - !ruby/object:Gem::Version
181
- version: '10.0'
201
+ version: '13.0'
182
202
  type: :development
183
203
  prerelease: false
184
204
  version_requirements: !ruby/object:Gem::Requirement
185
205
  requirements:
186
206
  - - "~>"
187
207
  - !ruby/object:Gem::Version
188
- version: '10.0'
208
+ version: '13.0'
189
209
  description: creates and manages resources for the aws client vpn
190
210
  email:
191
211
  - guslington@gmail.com
@@ -194,6 +214,9 @@ executables:
194
214
  extensions: []
195
215
  extra_rdoc_files: []
196
216
  files:
217
+ - ".github/workflows/build-gem.yml"
218
+ - ".github/workflows/release-gem.yml"
219
+ - ".github/workflows/release-image.yml"
197
220
  - ".gitignore"
198
221
  - ".travis.yml"
199
222
  - Dockerfile
@@ -203,26 +226,37 @@ files:
203
226
  - README.md
204
227
  - Rakefile
205
228
  - cfn-vpn.gemspec
229
+ - docs/README.md
230
+ - docs/certificate-users.md
231
+ - docs/getting-started.md
232
+ - docs/modifying.md
233
+ - docs/routes.md
234
+ - docs/scheduling.md
235
+ - docs/sessions.md
206
236
  - exe/cfn-vpn
207
237
  - lib/cfnvpn.rb
208
238
  - lib/cfnvpn/acm.rb
239
+ - lib/cfnvpn/actions/client.rb
240
+ - lib/cfnvpn/actions/embedded.rb
241
+ - lib/cfnvpn/actions/init.rb
242
+ - lib/cfnvpn/actions/modify.rb
243
+ - lib/cfnvpn/actions/params.rb
244
+ - lib/cfnvpn/actions/revoke.rb
245
+ - lib/cfnvpn/actions/routes.rb
246
+ - lib/cfnvpn/actions/sessions.rb
247
+ - lib/cfnvpn/actions/share.rb
248
+ - lib/cfnvpn/actions/subnets.rb
209
249
  - lib/cfnvpn/certificates.rb
210
- - lib/cfnvpn/cfhighlander.rb
211
- - lib/cfnvpn/client.rb
212
250
  - lib/cfnvpn/clientvpn.rb
213
- - lib/cfnvpn/cloudformation.rb
251
+ - lib/cfnvpn/compiler.rb
214
252
  - lib/cfnvpn/config.rb
215
- - lib/cfnvpn/embedded.rb
253
+ - lib/cfnvpn/deployer.rb
216
254
  - lib/cfnvpn/globals.rb
217
- - lib/cfnvpn/init.rb
218
255
  - lib/cfnvpn/log.rb
219
- - lib/cfnvpn/modify.rb
220
- - lib/cfnvpn/revoke.rb
221
- - lib/cfnvpn/routes.rb
222
256
  - lib/cfnvpn/s3.rb
223
- - lib/cfnvpn/sessions.rb
224
- - lib/cfnvpn/share.rb
225
- - lib/cfnvpn/templates/cfnvpn.cfhighlander.rb.tt
257
+ - lib/cfnvpn/string.rb
258
+ - lib/cfnvpn/templates/helper.rb
259
+ - lib/cfnvpn/templates/vpn.rb
226
260
  - lib/cfnvpn/version.rb
227
261
  homepage: https://github.com/base2services/aws-client-vpn
228
262
  licenses:
@@ -246,8 +280,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
280
  - !ruby/object:Gem::Version
247
281
  version: '0'
248
282
  requirements: []
249
- rubyforge_project:
250
- rubygems_version: 2.7.6
283
+ rubygems_version: 3.1.4
251
284
  signing_key:
252
285
  specification_version: 4
253
286
  summary: creates and manages resources for the aws client vpn