vcloud_ipsec-vpn 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3d7cf22aff44602471f4fb890db08e05823529ca
4
+ data.tar.gz: e0641d9bb77c6f2eb75c6c651a1e4e188a93908f
5
+ SHA512:
6
+ metadata.gz: 3f3c0964a5acb9cb76b6898e5e0ebc6d548abe50ad05165693a63ca9c5a10fff7c69c2c104c74b2c76fb8a9552964bd10180d8978dd7b6e0ee52a01c48662cbc
7
+ data.tar.gz: 86699c7e17a2181a2ed0d7771655de0f07637d46a1711ff548d7d47b98c54111208db4d52a7aafd0c7979466c2a48a5a8c7cff0b4b54efc3f897239cee54db7c
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ results.html
3
+ pkg
4
+ html
5
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vpnconfig.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,204 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Name: vpnconfig
191
+ Copyright 2015 Tim Gent
192
+
193
+
194
+ Licensed under the Apache License, Version 2.0 (the "License");
195
+ you may not use this file except in compliance with the License.
196
+ You may obtain a copy of the License at
197
+
198
+ http://www.apache.org/licenses/LICENSE-2.0
199
+
200
+ Unless required by applicable law or agreed to in writing, software
201
+ distributed under the License is distributed on an "AS IS" BASIS,
202
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
203
+ See the License for the specific language governing permissions and
204
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Vpnconfig
2
+ A command line tool to allow use of a yaml VPN configuration file to push this config to Skyscape
3
+
4
+ ## Installation
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'vpnconfig'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle install
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install vpnconfig
18
+
19
+ ## Usage
20
+ Run with option --help to show command line help.
21
+
22
+ Example command line with gem installed:
23
+ vpnconfig -d DataCentre1 -u JohnSmith -w vpn-configuration.yaml
24
+
25
+ Example command line if you have cloned the repository without installing as a gem:
26
+ bundle exec ./bin/vpnconfig -d DataCentre1 -u JohnSmith -w vpn-configuration.yaml
27
+
28
+ Example yaml input:
29
+ - name: MyVPNName
30
+ peerIp: 10.10.10.1
31
+ localIp: 80.10.10.1
32
+ localSubnet:
33
+ name: LocalSubnetNameHere
34
+ gateway: 10.80.2.0
35
+ netmask: 255.255.255.1
36
+ peerSubnet:
37
+ name: PeerSubnetNameHere
38
+ gateway: 10.80.2.1
39
+ netmask: 255.255.255.1
40
+ sharedSecret: itsasecret
41
+ - name: MySecondVPN
42
+ peerIp: 10.10.10.2
43
+ localIp: 80.10.10.2
44
+ localSubnet:
45
+ name: LocalSubnetName2
46
+ gateway: 10.80.2.1
47
+ netmask: 255.255.255.2
48
+ peerSubnet:
49
+ name: PeerSubnetName2
50
+ gateway: 10.80.2.2
51
+ netmask: 255.255.255.2
52
+ sharedSecret: itsasecret2
53
+ mtu: 2000
54
+
55
+ ## Development
56
+
57
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
58
+
59
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
60
+
61
+ ## Contributing
62
+
63
+ 1. Fork it ( https://github.com/UKHomeOffice/vcloud_ipec-vpn/fork )
64
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
65
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
66
+ 4. Push to the branch (`git push origin my-new-feature`)
67
+ 5. Create a new Pull Request
data/README.rdoc ADDED
@@ -0,0 +1,23 @@
1
+ = vpnconfig - DESCRIBE YOUR GEM
2
+
3
+ Author:: YOUR NAME (YOUR EMAIL)
4
+ Copyright:: Copyright (c) 2015 YOUR NAME
5
+
6
+
7
+ License:: apache, see LICENSE.txt
8
+
9
+
10
+
11
+ DESCRIBE YOUR GEM HERE
12
+
13
+ == Links
14
+
15
+ * {Source on Github}[LINK TO GITHUB]
16
+ * RDoc[LINK TO RDOC.INFO]
17
+
18
+ == Install
19
+
20
+ == Examples
21
+
22
+ == Contributing
23
+
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ def dump_load_path
2
+ puts $LOAD_PATH.join("\n")
3
+ found = nil
4
+ $LOAD_PATH.each do |path|
5
+ if File.exists?(File.join(path,"rspec"))
6
+ puts "Found rspec in #{path}"
7
+ if File.exists?(File.join(path,"rspec","core"))
8
+ puts "Found core"
9
+ if File.exists?(File.join(path,"rspec","core","rake_task"))
10
+ puts "Found rake_task"
11
+ found = path
12
+ else
13
+ puts "!! no rake_task"
14
+ end
15
+ else
16
+ puts "!!! no core"
17
+ end
18
+ end
19
+ end
20
+ if found.nil?
21
+ puts "Didn't find rspec/core/rake_task anywhere"
22
+ else
23
+ puts "Found in #{path}"
24
+ end
25
+ end
26
+ require 'bundler'
27
+ require 'rake/clean'
28
+
29
+ require 'rake/testtask'
30
+
31
+ require 'cucumber'
32
+ require 'cucumber/rake/task'
33
+ gem 'rdoc' # we need the installed RDoc gem, not the system one
34
+ require 'rdoc/task'
35
+
36
+ include Rake::DSL
37
+
38
+ Bundler::GemHelper.install_tasks
39
+
40
+
41
+ Rake::TestTask.new do |t|
42
+ t.pattern = 'test/tc_*.rb'
43
+ end
44
+
45
+
46
+ CUKE_RESULTS = 'results.html'
47
+ CLEAN << CUKE_RESULTS
48
+ Cucumber::Rake::Task.new(:features) do |t|
49
+ t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty --no-source -x"
50
+ t.fork = false
51
+ end
52
+
53
+ Rake::RDocTask.new do |rd|
54
+
55
+ rd.main = "README.rdoc"
56
+
57
+ rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
58
+ end
59
+
60
+ task :default => [:test,:features]
61
+
data/bin/vpnconfig ADDED
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'methadone'
5
+ require 'generator.rb'
6
+ require 'yaml'
7
+ require 'nokogiri'
8
+ require 'generator'
9
+ require 'validator'
10
+ require 'api'
11
+ require 'login'
12
+ require 'diffy'
13
+ require 'pp'
14
+ require 'fileutils'
15
+
16
+ class App
17
+ include Methadone::Main
18
+ include Methadone::CLILogging
19
+
20
+ # the main block
21
+ main do
22
+ @api = Vpnconfig::Api.new
23
+ @verbose = !options['v'].nil?
24
+ self.check_mandatory_inputs
25
+ input_config = self.validate_yaml_if_present(options['w'])
26
+
27
+ puts 'Logging in' if @verbose
28
+ conn = Vpnconfig::Login.new.login(options['u'])
29
+ puts "\nReading configuration...."
30
+ dc_details = @api.get_dc_details(conn, options['d'])
31
+ puts 'Found data centre: '+dc_details['name'] if @verbose
32
+ current_config, edgegw_href = @api.read_edgegw_config(dc_details, conn)
33
+
34
+ unless options['b'].nil?
35
+ self.backup_current_config(current_config, options['b'], options['d'])
36
+ end
37
+
38
+ puts 'Current configuration is:' if @verbose
39
+ puts current_config if @verbose
40
+ puts if @verbose
41
+
42
+ unless options['w'].nil?
43
+ puts 'Reading in your yaml file...' if @verbose
44
+
45
+ puts 'Generating XML...' if @verbose
46
+ new_config = Vpnconfig::Generator.new.generate_xml(input_config)
47
+ puts 'Generated XML is:' if @verbose
48
+ puts new_config if @verbose
49
+ puts if @verbose
50
+
51
+ if configs_match(current_config, new_config)
52
+ puts 'Old and new configuration are identical, no changes to make'
53
+ else
54
+ puts "Posting new configuration to skyscape"
55
+ puts "href: #{edgegw_href}..." if @verbose
56
+ task_href = @api.post_to_api(edgegw_href, conn, new_config)
57
+ puts 'Task has been created to update config, tracking progress....' if @verbose
58
+ report_task_status(task_href, conn)
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ # Supplemental methods
65
+ def self.validate_yaml_if_present(yaml_path)
66
+ if !yaml_path.nil?
67
+ input_config = YAML.load_file(yaml_path)
68
+ validation_errors = Vpnconfig::Validator.new.validate_yaml(input_config)
69
+
70
+ if !validation_errors.empty?
71
+ display_errors_and_abort(validation_errors)
72
+ end
73
+ end
74
+ input_config
75
+ end
76
+
77
+ def self.backup_current_config(current_config, backup_path, datacentre)
78
+ puts 'Creating backup of current configuration...' if @verbose
79
+ filename = Time.now.strftime("%Y%m%d%H%M%S") + '_' + datacentre + '_VPN_Config'
80
+ backup_path = backup_path + '/' if backup_path[-1] != '/'
81
+ filepath = backup_path + filename
82
+ unless File.directory?(filepath)
83
+ FileUtils.mkdir_p(backup_path)
84
+ puts 'Created directory for backup' if @verbose
85
+ end
86
+ File.write(filepath, current_config)
87
+ puts "Created backup file at: #{filepath}" if @verbose
88
+ end
89
+
90
+ def self.report_task_status(task_href, conn)
91
+ completed_task = @api.get_completed_task(task_href, conn)
92
+ if completed_task['status'] == 'success'
93
+ puts 'New config has been successfully written to Skyscape'
94
+ else
95
+ api_error_message = completed_task.at('Error')['message']
96
+ api_error_code= completed_task.at('Error')['majorErrorCode']
97
+ Kernel.abort("The task returned with status code #{api_error_code} and the following error: #{api_error_message}")
98
+ end
99
+ end
100
+
101
+ def self.check_mandatory_inputs
102
+ if options['d'].nil?
103
+ Kernel.abort('You must define a datacentre')
104
+ end
105
+ if options['u'].nil?
106
+ Kernel.abort('You must provide a username')
107
+ end
108
+ end
109
+
110
+ def self.save_config(xml_obj, filename)
111
+ file = File.open(filename, "w")
112
+ xml_obj.write_xml_to(file, options={})
113
+ file.close
114
+ end
115
+
116
+ def self.display_errors_and_abort(errors)
117
+ errors.each{|e| puts "#{e.message}"}
118
+ puts 'The schema to match against is:'
119
+ pp YAML.load_file('./lib/vpn-configuration-schema.yaml')
120
+ Kernel.abort('ERROR: Invalid yaml input does not match the schema, see validation_errors above.')
121
+ end
122
+
123
+ def self.configs_match(current_config, new_config)
124
+ new_config.delete(' ').lines.drop(1).join() == current_config.delete(' ')
125
+ end
126
+
127
+
128
+ # Command line interface details
129
+ description "Updates VPN configuration for given datacentre based on a yaml input file"
130
+
131
+ on("-w VAL", "--write", "Writes configuration to the VDC as per specified XML file")
132
+ on("-d VAL", "--datacentre", "Name of the skyscape datacentre")
133
+ on("-u VAL", "--user", "Username to connect to the Skyscape Datacenter(check API tab)")
134
+ on("-b VAL", "--backup", "Optionally specify the location to store a backup of the current configuration")
135
+ on("-v", "--verbose", "Verbose logging")
136
+
137
+ version Vpnconfig::VERSION
138
+
139
+ use_log_level_option :toggle_debug_on_signal => 'USR1'
140
+
141
+ go!
142
+ end
data/lib/api.rb ADDED
@@ -0,0 +1,133 @@
1
+ require "vpnconfig/version"
2
+
3
+ module Vpnconfig
4
+ class Api
5
+ def get_completed_task(task_href, conn)
6
+ def check_task_until_completed(task_href, conn)
7
+ task = get_xml_object(task_href, conn['auth_token'], 'Task')
8
+ if task['status'] == 'running'
9
+ sleep 1
10
+ check_task_until_completed(task_href, conn)
11
+ else
12
+ task
13
+ end
14
+ end
15
+
16
+ completed_task = check_task_until_completed(task_href, conn)
17
+ completed_task
18
+ end
19
+
20
+ def read_edgegw_config(dc, conn)
21
+ puts 'Getting details of dcs' if @verbose
22
+ edgegw_overviews = get_edgegw_overviews(dc, conn)
23
+ puts 'Getting details of edge gateways' if @verbose
24
+ edgegw_details = get_edgegw_details(edgegw_overviews, dc, conn)
25
+ #Get edge gateway config
26
+ puts 'Getting config of edge gateways' if @verbose
27
+ edgegw_configs = get_edgegw_configs(edgegw_details, dc, conn)
28
+ return edgegw_configs.to_s, edgegw_details.at('EdgeGatewayRecord')['href']
29
+ end
30
+
31
+ def post_to_api(href, conn, config)
32
+ task = push_config(href, conn['auth_token'], config)
33
+ task
34
+ end
35
+
36
+ def get_edgegw_configs(edgegw_details, dc, conn)
37
+ href = edgegw_details.at('EdgeGatewayRecord')['href']
38
+ get_xml_object(href, conn["auth_token"], 'EdgeGateway').at('Configuration').at('GatewayIpsecVpnService')
39
+ end
40
+
41
+ def get_edgegw_details(overview, dc, conn)
42
+ href = overview['href']
43
+ get_xml_object(href, conn['auth_token'], 'QueryResultRecords')
44
+ end
45
+
46
+ def get_edgegw_overviews(dc, conn)
47
+ dc_xml = get_xml_object(dc['href'], conn['auth_token'], 'Vdc')
48
+ overviews = dc_xml.search('Link[@rel="edgeGateways"]').to_a
49
+ if overviews.length > 1
50
+ Kernel.abort('More than 1 edge gateway found, aborting operation')
51
+ end
52
+ overviews[0]
53
+ end
54
+
55
+
56
+ def get_dc_details(conn, user_dc)
57
+ puts conn if @verbose
58
+ org_xml = get_xml_object(conn["org_url"], conn["auth_token"], 'Org')
59
+ all_dcs = get_all_dcs(org_xml)
60
+ matching_dcs = all_dcs.select { |dc| /^#{user_dc}/.match(dc['name']) || user_dc == dc['name'] }
61
+ if matching_dcs.length < 1
62
+ all_dc_names = all_dcs.map { |dc| dc['name'] }.join(', ')
63
+ Kernel.abort('No DCs match the search string: '+user_dc+'. All available DCs are: '+all_dc_names+'. Please use one of these')
64
+ elsif matching_dcs.length > 1
65
+ all_matching_names = matching_dcs.map { |dc| dc['name'] }.join(', ')
66
+ Kernel.abort('More than 1 DC matches the search string. Please be more specific. Matching DCs are: '+all_matching_names)
67
+ end
68
+ matching_dcs[0]
69
+ end
70
+
71
+
72
+ def get_all_dcs(org_xml)
73
+ org_xml.search('Link[@type="application/vnd.vmware.vcloud.vdc+xml"]').to_a
74
+ end
75
+
76
+ def get_xml_object(href, token, object_name)
77
+ begin
78
+ obj = nil
79
+ uri = URI.parse(href)
80
+ http = Net::HTTP.new(uri.host, uri.port)
81
+ http.use_ssl = true
82
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
83
+ request = Net::HTTP::Get.new(uri.request_uri, {'Accept' => 'application/*+xml;version=5.5', 'x-vcloud-authorization' => token})
84
+
85
+ response = http.request(request)
86
+ if response.code.to_i == 200
87
+ doc = Nokogiri::XML(response.body)
88
+ obj = doc.search(object_name).to_a
89
+ if obj.count == 1
90
+ return obj[0]
91
+ else
92
+ raise "The number of #{object_name} objects returned is not equal to 1! #{obj.inspect} "
93
+ end
94
+ else
95
+ raise "Error fetch the object #{object_name}, URL: #{href}, response code: #{response.code}"
96
+ end
97
+ rescue Exception => e
98
+ puts "Error fetching the object #{object_name}, URL: #{href}"
99
+ puts e
100
+ end
101
+ end
102
+
103
+ def push_config(href,token,config)
104
+ href = href + "/action/configureServices"
105
+
106
+ uri = URI.parse(href)
107
+ http = Net::HTTP.new(uri.host, uri.port)
108
+ http.use_ssl = true
109
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
110
+ request = Net::HTTP::Post.new(uri.request_uri, { 'Accept' => 'application/*+xml;version=5.5', 'x-vcloud-authorization' => token })
111
+ request.body = config.to_s
112
+ request.content_type = 'application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml'
113
+
114
+
115
+ response = http.request(request)
116
+ if response.code.to_i == 202
117
+ puts "Post successful" if @verbose
118
+ else
119
+ puts "Unexpected exit code"
120
+ puts response.code
121
+ puts response.body
122
+ end
123
+ task = get_task_href(response.body)
124
+ task
125
+ end
126
+
127
+ def get_task_href(response_body)
128
+ xml_doc = Nokogiri::XML(response_body)
129
+ task = xml_doc.at_css("Task")["href"]
130
+ task
131
+ end
132
+ end
133
+ end
data/lib/generator.rb ADDED
@@ -0,0 +1,47 @@
1
+ require "vpnconfig/version"
2
+
3
+ module Vpnconfig
4
+ class Generator
5
+ def generate_xml(input_configs)
6
+
7
+ xml = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
8
+ xml.EdgeGatewayServiceConfiguration('xmlns' => 'http://www.vmware.com/vcloud/v1.5') {
9
+ xml.GatewayIpsecVpnService {
10
+ xml.IsEnabled true
11
+ input_configs.each do |input_config|
12
+ xml.Tunnel {
13
+ xml.Name input_config['name']
14
+ xml.Description
15
+ xml.IpsecVpnThirdPartyPeer {
16
+ xml.PeerId input_config['peerIp']
17
+ }
18
+ xml.PeerIpAddress input_config['peerIp']
19
+ xml.PeerId input_config['peerIp']
20
+ xml.LocalIpAddress input_config['localIp']
21
+ xml.LocalId input_config['localIp']
22
+ xml.LocalSubnet {
23
+ xml.Name input_config['localSubnet']['name']
24
+ xml.Gateway input_config['localSubnet']['gateway']
25
+ xml.Netmask input_config['localSubnet']['netmask']
26
+ }
27
+ xml.PeerSubnet {
28
+ xml.Name input_config['peerSubnet']['name']
29
+ xml.Gateway input_config['peerSubnet']['gateway']
30
+ xml.Netmask input_config['peerSubnet']['netmask']
31
+ }
32
+ xml.SharedSecret input_config['sharedSecret']
33
+ xml.SharedSecretEncrypted false
34
+ xml.EncryptionProtocol 'AES256'
35
+ xml.Mtu input_config.fetch('mtu', '1500')
36
+ xml.IsEnabled 'true'
37
+ xml.IsOperational 'false'
38
+ }
39
+ end
40
+ }
41
+ }
42
+ end
43
+
44
+ xml.to_xml
45
+ end
46
+ end
47
+ end
data/lib/login.rb ADDED
@@ -0,0 +1,37 @@
1
+ require "vpnconfig/version"
2
+
3
+ module Vpnconfig
4
+ class Login
5
+ def login(username)
6
+ print "Enter Password for user #{username}: "
7
+ password = STDIN.noecho(&:gets).chomp
8
+ puts '' if @verbose
9
+ puts 'Getting connection string...' if @verbose
10
+ conn = get_conn_string(username, password)
11
+ conn
12
+ end
13
+
14
+ def get_conn_string(username,password)
15
+ begin
16
+ uri = URI.parse("https://api.vcd.portal.skyscapecloud.com/api/sessions")
17
+ http = Net::HTTP.new(uri.host, uri.port)
18
+ http.use_ssl = true
19
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
20
+ request = Net::HTTP::Post.new(uri.request_uri, { 'Accept' => 'application/*+xml;version=5.5' })
21
+ request.basic_auth(username, password)
22
+ response = http.request(request)
23
+ auth = response['x-vcloud-authorization'].to_s
24
+ if auth.nil? || auth.length != 44
25
+ puts "there is something wrong with the auth token: #{auth}"
26
+ end
27
+ rescue Exception => e
28
+ puts "Error getting auth Token"
29
+ puts e
30
+ end
31
+ doc = Nokogiri::XML(response.body)
32
+ session = doc.at('Session')
33
+ org_href = session.at('Link[@type="application/vnd.vmware.vcloud.org+xml"]')['href']
34
+ return { "auth_token" => auth, "org_url" => org_href.to_s }
35
+ end
36
+ end
37
+ end
data/lib/validator.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "vpnconfig/version"
2
+ require 'kwalify'
3
+
4
+ module Vpnconfig
5
+ class Validator
6
+ def validate_yaml(yaml)
7
+ schema = Kwalify::Yaml.load_file('lib/vpn-configuration-schema.yaml')
8
+ validator = Kwalify::Validator.new(schema)
9
+ errors = validator.validate(yaml)
10
+ errors
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ type: seq
2
+ sequence:
3
+ - type: map
4
+ mapping:
5
+ "name":
6
+ type: str
7
+ required: yes
8
+ "peerIp":
9
+ type: str
10
+ required: yes
11
+ "localIp":
12
+ type: str
13
+ required: yes
14
+ "localSubnet":
15
+ type: map
16
+ required: yes
17
+ mapping:
18
+ "name":
19
+ type: str
20
+ required: yes
21
+ "gateway":
22
+ type: str
23
+ required: yes
24
+ "netmask":
25
+ type: str
26
+ required: yes
27
+ "peerSubnet":
28
+ type: map
29
+ required: yes
30
+ mapping:
31
+ "name":
32
+ type: str
33
+ required: yes
34
+ "gateway":
35
+ type: str
36
+ required: yes
37
+ "netmask":
38
+ type: str
39
+ required: yes
40
+ "sharedSecret":
41
+ type: str
42
+ required: yes
43
+ "mtu":
44
+ type: number
45
+ required: no
@@ -0,0 +1,3 @@
1
+ module Vpnconfig
2
+ VERSION = "0.1.0"
3
+ end
data/vpnconfig.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vpnconfig/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vcloud_ipsec-vpn"
8
+ spec.description = "A command line tool to allow use of a yaml configuration file to configure VPNs on a given DC on Skyscape infrastructure"
9
+ spec.version = Vpnconfig::VERSION
10
+ spec.authors = ["Tim Gent"]
11
+ spec.email = ["tim.gent@gmail.com"]
12
+
13
+ spec.summary = "Configures VPNs in Skyscape"
14
+ spec.homepage = "https://github.com/UKHomeOffice/vcloud_ipec-vpn"
15
+ spec.license = "apache"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f)}
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.8'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rdoc', '~> 4.2', '>= 4.2.0'
24
+ spec.add_development_dependency('aruba', '~> 0.6.2')
25
+ spec.add_development_dependency 'test-unit', '~> 3.1', '>= 3.1.2'
26
+ spec.add_dependency('methadone', '~> 1.9', '>= 1.9.1')
27
+ spec.add_dependency 'nokogiri', '~> 1.6', '>= 1.6.6.2'
28
+ spec.add_dependency('diffy', '~> 3.0', '>= 3.0.7')
29
+ spec.add_dependency('kwalify', '~> 0.7.2')
30
+ end
metadata ADDED
@@ -0,0 +1,217 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vcloud_ipsec-vpn
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Gent
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.2'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 4.2.0
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '4.2'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 4.2.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: aruba
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.6.2
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.6.2
75
+ - !ruby/object:Gem::Dependency
76
+ name: test-unit
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.1'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 3.1.2
85
+ type: :development
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '3.1'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 3.1.2
95
+ - !ruby/object:Gem::Dependency
96
+ name: methadone
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '1.9'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.9.1
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.9'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 1.9.1
115
+ - !ruby/object:Gem::Dependency
116
+ name: nokogiri
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '1.6'
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 1.6.6.2
125
+ type: :runtime
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.6'
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: 1.6.6.2
135
+ - !ruby/object:Gem::Dependency
136
+ name: diffy
137
+ requirement: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: '3.0'
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 3.0.7
145
+ type: :runtime
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '3.0'
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: 3.0.7
155
+ - !ruby/object:Gem::Dependency
156
+ name: kwalify
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: 0.7.2
162
+ type: :runtime
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: 0.7.2
169
+ description: A command line tool to allow use of a yaml configuration file to configure
170
+ VPNs on a given DC on Skyscape infrastructure
171
+ email:
172
+ - tim.gent@gmail.com
173
+ executables:
174
+ - vpnconfig
175
+ extensions: []
176
+ extra_rdoc_files: []
177
+ files:
178
+ - ".gitignore"
179
+ - Gemfile
180
+ - LICENSE.txt
181
+ - README.md
182
+ - README.rdoc
183
+ - Rakefile
184
+ - bin/vpnconfig
185
+ - lib/api.rb
186
+ - lib/generator.rb
187
+ - lib/login.rb
188
+ - lib/validator.rb
189
+ - lib/vpn-configuration-schema.yaml
190
+ - lib/vpnconfig/version.rb
191
+ - vpnconfig.gemspec
192
+ homepage: https://github.com/UKHomeOffice/vcloud_ipec-vpn
193
+ licenses:
194
+ - apache
195
+ metadata: {}
196
+ post_install_message:
197
+ rdoc_options: []
198
+ require_paths:
199
+ - lib
200
+ required_ruby_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ required_rubygems_version: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ requirements: []
211
+ rubyforge_project:
212
+ rubygems_version: 2.4.6
213
+ signing_key:
214
+ specification_version: 4
215
+ summary: Configures VPNs in Skyscape
216
+ test_files: []
217
+ has_rdoc: