nymphia 0.1.0
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +214 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/base.rb +19 -0
- data/examples/company.rb +54 -0
- data/examples/result.example +56 -0
- data/exe/nymphia +5 -0
- data/lib/nymphia.rb +14 -0
- data/lib/nymphia/cli.rb +48 -0
- data/lib/nymphia/dsl.rb +24 -0
- data/lib/nymphia/dsl/context.rb +45 -0
- data/lib/nymphia/dsl/context/default_params.rb +17 -0
- data/lib/nymphia/dsl/context/gateway.rb +6 -0
- data/lib/nymphia/dsl/context/group.rb +15 -0
- data/lib/nymphia/dsl/context/host.rb +38 -0
- data/lib/nymphia/dsl/context/host_context_methods.rb +26 -0
- data/lib/nymphia/dsl/context/proxy.rb +21 -0
- data/lib/nymphia/dsl/context/use_gateway.rb +8 -0
- data/lib/nymphia/dsl/recursive_methods.rb +52 -0
- data/lib/nymphia/ssh_config_template.erb +19 -0
- data/lib/nymphia/version.rb +3 -0
- data/nymphia.gemspec +29 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7043bb4311731bcf68cdd37767d4f99eeba931c1
|
4
|
+
data.tar.gz: 3adb21ed393c2c1b7408dd72234fd49e37ee5e4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4fa288c3ca3fe525d68ea6fd54b951a7e9aabdc46e81eaab66daecfd7c9412ff798bf9f636366337f8d61ef0ecedd504ef0b68891290b26c33ae7fd95571160e
|
7
|
+
data.tar.gz: 064980bb9445f5aa662a363547644fe0e36b0d558647cd036b2d51ba391e1347371b3d2ad2f8e307c4f4b96ec4693fd81d28fe9dcf4fc28078c10c99294fc4ff
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 mozamimy (Moza USANE)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
# Nymphia
|
2
|
+
|
3
|
+
Nymphia is a DSL to generate a ssh config file more structurally.
|
4
|
+
You can use full Ruby syntax and useful methods provided by Nymphia.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Just type gem command,
|
9
|
+
|
10
|
+
```
|
11
|
+
$ gem install nymphia
|
12
|
+
```
|
13
|
+
|
14
|
+
## CLI interface
|
15
|
+
|
16
|
+
```
|
17
|
+
$ nymphia --help
|
18
|
+
nymphia
|
19
|
+
-f, --file=FILE Your DSL code file
|
20
|
+
-o, --output=FILE Output file (default: stdout)
|
21
|
+
```
|
22
|
+
|
23
|
+
## Getting started
|
24
|
+
|
25
|
+
### Basis
|
26
|
+
|
27
|
+
Following code is a small example.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
identity_file :private, '~/.ssh/id_rsa.1'
|
31
|
+
|
32
|
+
my_server_port = 4321
|
33
|
+
|
34
|
+
host 'alice', 'my server on VPS' do
|
35
|
+
hostname 'alice.example.com'
|
36
|
+
user 'alice'
|
37
|
+
port my_server_port
|
38
|
+
use_identify_file :private
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
Following ssh config file is generated after the code is compiled.
|
43
|
+
|
44
|
+
```
|
45
|
+
#
|
46
|
+
# This config is generated by Nymphia 0.1.0
|
47
|
+
#
|
48
|
+
|
49
|
+
# my server on VPS
|
50
|
+
Host alice
|
51
|
+
Hostname alice.example.com
|
52
|
+
User alice
|
53
|
+
Port 4321
|
54
|
+
IdentityFile ~/.ssh/id_rsa.1
|
55
|
+
```
|
56
|
+
|
57
|
+
Method `identity_file` register your identity file with a name. You can use registered identity file by `use_identify_file` in `host` block.
|
58
|
+
|
59
|
+
Method `host` generate `Host` directive. First argument is name of host, Second argument is description of the host. Description is optional.
|
60
|
+
|
61
|
+
### Splitting files
|
62
|
+
|
63
|
+
You can use `load` method to load other Nymphia file like following example. Absolute path and relative path are acceptable as the file path.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
identity_file :private, '~/.ssh/id_rsa.1'
|
67
|
+
|
68
|
+
host 'alice', 'my server on VPS' do
|
69
|
+
hostname 'alice.example.com'
|
70
|
+
user 'alice'
|
71
|
+
port 4321
|
72
|
+
use_identify_file :private
|
73
|
+
end
|
74
|
+
|
75
|
+
load 'other_nymphia_file.rb'
|
76
|
+
```
|
77
|
+
|
78
|
+
### Proxy method
|
79
|
+
|
80
|
+
Method `proxy` is almost same to `host`, but `local_forward` method can be used in `proxy`. Following code is small example of `proxy`.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
identity_file :company_gateway, '~/.ssh/id_rsa.company.gw'
|
84
|
+
|
85
|
+
proxy 'awsproxy.company.apne1' do
|
86
|
+
hostname 'gw.apne1.example.com'
|
87
|
+
user 'alice'
|
88
|
+
port 19822
|
89
|
+
use_identify_file :company_gateway
|
90
|
+
|
91
|
+
# SOCKS proxy
|
92
|
+
dynamic_forward 23921
|
93
|
+
|
94
|
+
# ssh tunnels
|
95
|
+
local_forward 'mysql-server', {
|
96
|
+
'localhost' => 13306,
|
97
|
+
'mysql.apne.aws.example.com' => 3306,
|
98
|
+
}
|
99
|
+
|
100
|
+
local_forward 'ldap', {
|
101
|
+
'localhost' => 10389,
|
102
|
+
'ldap.apne.aws.example.com' => 398,
|
103
|
+
}
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
Following ssh config file is generated after the code is compiled.
|
108
|
+
|
109
|
+
```
|
110
|
+
#
|
111
|
+
# This config is generated by Nymphia 0.1.0
|
112
|
+
#
|
113
|
+
|
114
|
+
Host awsproxy.company.apne1
|
115
|
+
Hostname gw.apne1.example.com
|
116
|
+
User alice
|
117
|
+
Port 19822
|
118
|
+
IdentityFile ~/.ssh/id_rsa.company.gw
|
119
|
+
DynamicForward 23921
|
120
|
+
LocalForward localhost:13306 mysql.apne.aws.example.com:3306
|
121
|
+
LocalForward localhost:10389 ldap.apne.aws.example.com:398
|
122
|
+
```
|
123
|
+
|
124
|
+
### Advanced: Grouping and use_gateway, default_params
|
125
|
+
|
126
|
+
Nymphia has `group` and `gateway` method to make ssh config more structurally. Following code is small example of grouping.
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
identity_file :company, '~/.ssh/id_rsa.company'
|
130
|
+
identity_file :company_gateway, '~/.ssh/id_rsa.company.gw'
|
131
|
+
|
132
|
+
gateway 'company.gateway' do
|
133
|
+
hostname 'gw.example.com'
|
134
|
+
user 'alice'
|
135
|
+
port 19822
|
136
|
+
end
|
137
|
+
|
138
|
+
group 'company.ap-northeast-1' do
|
139
|
+
use_gateway 'company.gateway'
|
140
|
+
|
141
|
+
default_params do
|
142
|
+
check_host_ip 'no'
|
143
|
+
strict_host_key_checking 'no'
|
144
|
+
user 'alice'
|
145
|
+
port 9822
|
146
|
+
use_identify_file :company, :company_gateway
|
147
|
+
end
|
148
|
+
|
149
|
+
host '*.apne.aws.example.com'
|
150
|
+
|
151
|
+
host 'alice.apne.aws.example.com' do
|
152
|
+
hostname '10.16.16.16'
|
153
|
+
user 'white_rabbit'
|
154
|
+
port 7777
|
155
|
+
end
|
156
|
+
end
|
157
|
+
```
|
158
|
+
|
159
|
+
Following ssh config file is generated after the code is compiled.
|
160
|
+
|
161
|
+
```
|
162
|
+
|
163
|
+
#
|
164
|
+
# This config is generated by Nymphia 0.1.0
|
165
|
+
#
|
166
|
+
|
167
|
+
Host company.gateway
|
168
|
+
Hostname gw.example.com
|
169
|
+
User alice
|
170
|
+
Port 19822
|
171
|
+
|
172
|
+
Host *.apne.aws.example.com
|
173
|
+
CheckHostIp no
|
174
|
+
StrictHostKeyChecking no
|
175
|
+
User alice
|
176
|
+
Port 9822
|
177
|
+
IdentityFile ~/.ssh/id_rsa.company
|
178
|
+
IdentityFile ~/.ssh/id_rsa.company.gw
|
179
|
+
ProxyCommand ssh company.gateway -q -W %h:%p
|
180
|
+
|
181
|
+
Host alice.apne.aws.example.com
|
182
|
+
CheckHostIp no
|
183
|
+
StrictHostKeyChecking no
|
184
|
+
IdentityFile ~/.ssh/id_rsa.company
|
185
|
+
IdentityFile ~/.ssh/id_rsa.company.gw
|
186
|
+
ProxyCommand ssh company.gateway -q -W %h:%p
|
187
|
+
Hostname 10.16.16.16
|
188
|
+
User white_rabbit
|
189
|
+
Port 7777
|
190
|
+
```
|
191
|
+
|
192
|
+
Method `gateway` is almost same to `host`, but it can be used in a group by `use_gateway` method. When write `use_gateway` in a group, `ProxyCommand ssh #{gateway name} -q -W %h:%p` directive is added automatically to hosts in the group.
|
193
|
+
|
194
|
+
Method `default_params` defines default parameters of hosts in the group including `default_params`. In this example, `host '*.apne.aws.example.com'` has no parameters, but `Host *.apne.aws.example.com` in result is filled by default parameters. The default parameters can be overide like `host 'alice.apne.aws.example.com'`.
|
195
|
+
|
196
|
+
## Todo
|
197
|
+
|
198
|
+
- [ ] vim syntax
|
199
|
+
- [ ] Test code
|
200
|
+
- [ ] CI
|
201
|
+
|
202
|
+
## Development
|
203
|
+
|
204
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
205
|
+
|
206
|
+
## Contributing
|
207
|
+
|
208
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mozamimy/nymphia.
|
209
|
+
|
210
|
+
|
211
|
+
## License
|
212
|
+
|
213
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
214
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "nymphia"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/examples/base.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
identity_file :private, '~/.ssh/id_rsa.1'
|
2
|
+
|
3
|
+
my_server_port = 4321
|
4
|
+
|
5
|
+
host 'alice', 'my server on VPS' do
|
6
|
+
hostname 'alice.example.com'
|
7
|
+
user 'alice'
|
8
|
+
port my_server_port
|
9
|
+
use_identify_file :private
|
10
|
+
end
|
11
|
+
|
12
|
+
host 'queen', 'NAS in my home network' do
|
13
|
+
hostname '172.16.16.3'
|
14
|
+
user 'alice'
|
15
|
+
port my_server_port
|
16
|
+
use_identify_file :private
|
17
|
+
end
|
18
|
+
|
19
|
+
load 'company.rb'
|
data/examples/company.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
identity_file :company, '~/.ssh/id_rsa.company'
|
2
|
+
identity_file :company_gateway, '~/.ssh/id_rsa.company.gw'
|
3
|
+
identity_file :company_internal, '~/.ssh/id_rsa.company.in'
|
4
|
+
|
5
|
+
gateway 'company.gateway', 'Gateway saerver of my company' do
|
6
|
+
hostname 'gw.example.com'
|
7
|
+
user 'alice'
|
8
|
+
port 19822
|
9
|
+
end
|
10
|
+
|
11
|
+
group 'company.ap-northeast-1' do
|
12
|
+
use_gateway 'company.gateway'
|
13
|
+
|
14
|
+
default_params do
|
15
|
+
check_host_ip 'no'
|
16
|
+
strict_host_key_checking 'no'
|
17
|
+
user 'alice'
|
18
|
+
port 9822
|
19
|
+
use_identify_file :company, :company_gateway
|
20
|
+
end
|
21
|
+
|
22
|
+
host '*.apne.aws.example.com'
|
23
|
+
|
24
|
+
host 'alice.apne.aws.example.com' do
|
25
|
+
hostname '10.16.16.16'
|
26
|
+
user 'white_rabbit'
|
27
|
+
port 7777
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
proxy 'awsproxy.company.apne1' do
|
32
|
+
hostname 'gw.apne1.example.com'
|
33
|
+
user 'alice'
|
34
|
+
port 19822
|
35
|
+
use_identify_file :company_gateway
|
36
|
+
|
37
|
+
# SOCKS proxy
|
38
|
+
dynamic_forward 23921
|
39
|
+
|
40
|
+
# ssh tunnels
|
41
|
+
local_forward 'mysql-server', {
|
42
|
+
'localhost' => 13306,
|
43
|
+
'mysql.apne.aws.example.com' => 3306,
|
44
|
+
}
|
45
|
+
|
46
|
+
local_forward 'ldap', {
|
47
|
+
'localhost' => 10389,
|
48
|
+
'ldap.apne.aws.example.com' => 398,
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
host 'ghe.company.example.com' do
|
53
|
+
use_identify_file :company_internal
|
54
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#
|
2
|
+
# This config is generated by Nymphia 0.1.0
|
3
|
+
#
|
4
|
+
|
5
|
+
# my server on VPS
|
6
|
+
Host alice
|
7
|
+
Hostname alice.example.com
|
8
|
+
User alice
|
9
|
+
Port 4321
|
10
|
+
IdentityFile ~/.ssh/id_rsa.1
|
11
|
+
|
12
|
+
# NAS in my home network
|
13
|
+
Host queen
|
14
|
+
Hostname 172.16.16.3
|
15
|
+
User alice
|
16
|
+
Port 4321
|
17
|
+
IdentityFile ~/.ssh/id_rsa.1
|
18
|
+
|
19
|
+
# Gateway saerver of my company
|
20
|
+
Host company.gateway
|
21
|
+
Hostname gw.example.com
|
22
|
+
User alice
|
23
|
+
Port 19822
|
24
|
+
|
25
|
+
Host *.apne.aws.example.com
|
26
|
+
CheckHostIp no
|
27
|
+
StrictHostKeyChecking no
|
28
|
+
User alice
|
29
|
+
Port 9822
|
30
|
+
IdentityFile ~/.ssh/id_rsa.company
|
31
|
+
IdentityFile ~/.ssh/id_rsa.company.gw
|
32
|
+
ProxyCommand ssh company.gateway -q -W %h:%p
|
33
|
+
|
34
|
+
Host alice.apne.aws.example.com
|
35
|
+
CheckHostIp no
|
36
|
+
StrictHostKeyChecking no
|
37
|
+
IdentityFile ~/.ssh/id_rsa.company
|
38
|
+
IdentityFile ~/.ssh/id_rsa.company.gw
|
39
|
+
ProxyCommand ssh company.gateway -q -W %h:%p
|
40
|
+
Hostname 10.16.16.16
|
41
|
+
User white_rabbit
|
42
|
+
Port 7777
|
43
|
+
|
44
|
+
Host awsproxy.company.apne1
|
45
|
+
Hostname gw.apne1.example.com
|
46
|
+
User alice
|
47
|
+
Port 19822
|
48
|
+
IdentityFile ~/.ssh/id_rsa.company.gw
|
49
|
+
DynamicForward 23921
|
50
|
+
LocalForward localhost:13306 mysql.apne.aws.example.com:3306
|
51
|
+
LocalForward localhost:10389 ldap.apne.aws.example.com:398
|
52
|
+
|
53
|
+
Host ghe.company.example.com
|
54
|
+
IdentityFile ~/.ssh/id_rsa.company.in
|
55
|
+
|
56
|
+
|
data/exe/nymphia
ADDED
data/lib/nymphia.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'nymphia/cli'
|
2
|
+
require 'nymphia/dsl'
|
3
|
+
require 'nymphia/version'
|
4
|
+
require 'nymphia/dsl/recursive_methods'
|
5
|
+
require 'nymphia/dsl/context'
|
6
|
+
require 'nymphia/dsl/context/host_context_methods'
|
7
|
+
require 'nymphia/dsl/context/default_params'
|
8
|
+
require 'nymphia/dsl/context/use_gateway'
|
9
|
+
require 'nymphia/dsl/context/host'
|
10
|
+
require 'nymphia/dsl/context/gateway'
|
11
|
+
require 'nymphia/dsl/context/proxy'
|
12
|
+
require 'nymphia/dsl/context/group'
|
13
|
+
|
14
|
+
module Nymphia; end
|
data/lib/nymphia/cli.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'nymphia'
|
2
|
+
require 'optparse'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
class Nymphia::CLI
|
6
|
+
def self.start(argv)
|
7
|
+
new(argv).run
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(argv)
|
11
|
+
@argv = argv.dup
|
12
|
+
parser.parse!(@argv)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
validate_args!
|
17
|
+
|
18
|
+
dsl_code_file = File.open(@file_path)
|
19
|
+
absolute_dsl_file_path = File.absolute_path(dsl_code_file.path)
|
20
|
+
dsl_code = dsl_code_file.read
|
21
|
+
|
22
|
+
dsl = Nymphia::DSL.new(dsl_code, absolute_dsl_file_path)
|
23
|
+
dsl.compile
|
24
|
+
|
25
|
+
if @output_file_path
|
26
|
+
dsl.render(File.open(@output_file_path, 'w'))
|
27
|
+
else
|
28
|
+
dsl.render(STDOUT)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def parser
|
35
|
+
@parser ||= OptionParser.new do |opts|
|
36
|
+
opts.banner = 'nymphia'
|
37
|
+
opts.version = Nymphia::VERSION
|
38
|
+
opts.on('-f', '--file=FILE', 'Your DSL code file') { |f| @file_path = f }
|
39
|
+
opts.on('-o', '--output=FILE', 'Output file (default: stdout)') { |o| @output_file_path = o }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate_args!
|
44
|
+
unless @file_path
|
45
|
+
raise ArgumentError.new('-f (--file) options is required.')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/nymphia/dsl.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
class Nymphia::DSL
|
5
|
+
def initialize(dsl_code, path)
|
6
|
+
@dsl_code = dsl_code
|
7
|
+
@path = path
|
8
|
+
end
|
9
|
+
|
10
|
+
def compile
|
11
|
+
@result = Nymphia::DSL::Context.eval(@dsl_code, @path).result
|
12
|
+
end
|
13
|
+
|
14
|
+
def render(output)
|
15
|
+
ssh_config = ERB.new(File.read(find_template('ssh_config_template.erb')), nil, '-').result(binding)
|
16
|
+
output.write(ssh_config)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def find_template(filename)
|
22
|
+
Pathname.new(__FILE__).dirname.join(filename)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
class Nymphia::DSL::Context
|
4
|
+
include Nymphia::DSL::RecursiveMethods
|
5
|
+
|
6
|
+
attr_reader :result
|
7
|
+
|
8
|
+
def self.eval(dsl_code, path)
|
9
|
+
new(path) do
|
10
|
+
eval(dsl_code, binding, path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(path, &block)
|
15
|
+
@path = path
|
16
|
+
|
17
|
+
@context = {
|
18
|
+
identity_files: {},
|
19
|
+
gateways: {},
|
20
|
+
default_params: {},
|
21
|
+
gateway_usage: {},
|
22
|
+
}
|
23
|
+
|
24
|
+
@result = {
|
25
|
+
hosts: [],
|
26
|
+
}
|
27
|
+
|
28
|
+
instance_eval(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def identity_file(name, path)
|
34
|
+
name = name.to_s
|
35
|
+
path = path.to_s
|
36
|
+
@context[:identity_files][name] = path
|
37
|
+
end
|
38
|
+
|
39
|
+
def load(load_file_path)
|
40
|
+
absolute_load_file_path = Pathname.new(@path).dirname.join(load_file_path)
|
41
|
+
dsl_code = File.read(absolute_load_file_path)
|
42
|
+
|
43
|
+
instance_eval(dsl_code, absolute_load_file_path.to_s)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
class Nymphia::DSL::Context::DefaultParams
|
5
|
+
include Nymphia::DSL::Context::HostContextMethods
|
6
|
+
|
7
|
+
attr_reader :result
|
8
|
+
|
9
|
+
def initialize(context, &block)
|
10
|
+
@context = context
|
11
|
+
@result = {
|
12
|
+
contents: {},
|
13
|
+
}
|
14
|
+
|
15
|
+
instance_eval(&block)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class Nymphia::DSL::Context::Gateway < Nymphia::DSL::Context::Host
|
2
|
+
def initialize(context, name, description, default_params, gateway_usage, &block)
|
3
|
+
super(context, name, description, default_params, gateway_usage, &block)
|
4
|
+
@context[:gateways][name] = @result
|
5
|
+
end
|
6
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Nymphia::DSL::Context::Group
|
2
|
+
include Nymphia::DSL::RecursiveMethods
|
3
|
+
|
4
|
+
attr_reader :result
|
5
|
+
|
6
|
+
def initialize(context, name, &block)
|
7
|
+
@group_name = name
|
8
|
+
@context = context
|
9
|
+
@result = {
|
10
|
+
hosts: [],
|
11
|
+
}
|
12
|
+
|
13
|
+
instance_eval(&block)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
class Nymphia::DSL::Context::Host
|
5
|
+
include Nymphia::DSL::Context::HostContextMethods
|
6
|
+
|
7
|
+
attr_reader :result
|
8
|
+
|
9
|
+
def initialize(context, name, description, default_params, gateway_usage, &block)
|
10
|
+
@host_name = name
|
11
|
+
@context = context.merge(host_name: name)
|
12
|
+
@result = {
|
13
|
+
metadata: {
|
14
|
+
host_name: name,
|
15
|
+
description: description,
|
16
|
+
},
|
17
|
+
}
|
18
|
+
|
19
|
+
if default_params.nil?
|
20
|
+
@result[:contents] = {}
|
21
|
+
else
|
22
|
+
@default_params = default_params.dup
|
23
|
+
@result[:contents] = @default_params
|
24
|
+
end
|
25
|
+
|
26
|
+
unless gateway_usage.nil?
|
27
|
+
proxy_command = "ssh #{@context[:gateways][gateway_usage][:metadata][:host_name]} -q -W %h:%p"
|
28
|
+
|
29
|
+
if @result[:contents]['ProxyCommand']
|
30
|
+
@result[:contents]['ProxyCommand'] << proxy_command
|
31
|
+
else
|
32
|
+
@result[:contents]['ProxyCommand'] = Array(proxy_command)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
instance_eval(&block) if block
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Nymphia::DSL::Context::HostContextMethods
|
2
|
+
private
|
3
|
+
|
4
|
+
def use_identify_file(*identity_file_ids)
|
5
|
+
@result[:contents]['IdentityFile'] = []
|
6
|
+
|
7
|
+
identity_file_ids.each do |identity_file_id|
|
8
|
+
@result[:contents]['IdentityFile'] << @context[:identity_files][identity_file_id.to_s]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(method, *params)
|
13
|
+
key = method.to_s.camelize
|
14
|
+
|
15
|
+
if @default_params && @default_params[key]
|
16
|
+
@result[:contents][key] = Array(params[0])
|
17
|
+
@default_params.delete(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
if @result[:contents][key]
|
21
|
+
@result[:contents][key] << params[0]
|
22
|
+
else
|
23
|
+
@result[:contents][key] = Array(params[0])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Nymphia::DSL::Context::Proxy < Nymphia::DSL::Context::Host
|
2
|
+
def initialize(context, name, description, default_params, gateway_usage, &block)
|
3
|
+
super(context, name, description, default_params, gateway_usage, &block)
|
4
|
+
end
|
5
|
+
|
6
|
+
def local_forward(name, params)
|
7
|
+
name = name.to_s
|
8
|
+
|
9
|
+
local_forward_arg = ''
|
10
|
+
params.each do |host, port|
|
11
|
+
local_forward_arg << "#{host}:#{port} "
|
12
|
+
end
|
13
|
+
local_forward_arg.strip!
|
14
|
+
|
15
|
+
if @result[:contents]['LocalForward']
|
16
|
+
@result[:contents]['LocalForward'] << local_forward_arg
|
17
|
+
else
|
18
|
+
@result[:contents]['LocalForward'] = Array(local_forward_arg)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Nymphia::DSL::RecursiveMethods
|
2
|
+
private
|
3
|
+
|
4
|
+
def default_params(&block)
|
5
|
+
new_default_params = Nymphia::DSL::Context::DefaultParams.new(@context, &block).result[:contents]
|
6
|
+
@context[:default_params][@group_name] = new_default_params
|
7
|
+
end
|
8
|
+
|
9
|
+
def use_gateway(name)
|
10
|
+
name = name.to_s
|
11
|
+
|
12
|
+
new_gateway_usage = Nymphia::DSL::Context::UseGateway.new(@context, name).result
|
13
|
+
@context[:gateway_usage][@group_name] = new_gateway_usage
|
14
|
+
end
|
15
|
+
|
16
|
+
def host(name, description=nil, &block)
|
17
|
+
process_dsl_with(Nymphia::DSL::Context::Host, name, description, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def gateway(name, description=nil, &block)
|
21
|
+
process_dsl_with(Nymphia::DSL::Context::Gateway, name, description, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def proxy(name, description=nil, &block)
|
25
|
+
process_dsl_with(Nymphia::DSL::Context::Proxy, name, description, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def process_dsl_with(dsl_class, name, description, &block)
|
29
|
+
name = name.to_s
|
30
|
+
description = description.to_s if description
|
31
|
+
default_params = @context[:default_params][@group_name]
|
32
|
+
gateway_usage = @context[:gateway_usage][@group_name]
|
33
|
+
|
34
|
+
new_host = dsl_class.new(
|
35
|
+
@context,
|
36
|
+
name,
|
37
|
+
description,
|
38
|
+
default_params,
|
39
|
+
gateway_usage,
|
40
|
+
&block
|
41
|
+
).result
|
42
|
+
|
43
|
+
@result[:hosts] << new_host
|
44
|
+
end
|
45
|
+
|
46
|
+
def group(name, &block)
|
47
|
+
name = name.to_s
|
48
|
+
|
49
|
+
new_hosts = Nymphia::DSL::Context::Group.new(@context, name, &block).result[:hosts]
|
50
|
+
@result[:hosts].concat(new_hosts)
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# This config is generated by Nymphia <%= Nymphia::VERSION %>
|
3
|
+
#
|
4
|
+
|
5
|
+
<%- @result[:hosts].each do |host| -%>
|
6
|
+
<%- if host[:metadata][:description] -%>
|
7
|
+
# <%= host[:metadata][:description] %>
|
8
|
+
<%- end -%>
|
9
|
+
Host <%= host[:metadata][:host_name] %>
|
10
|
+
<%- host[:contents].each do |k, v| -%>
|
11
|
+
<%- if v.respond_to?(:each) -%>
|
12
|
+
<%- v.each do |w| -%>
|
13
|
+
<%= k %> <%= w %>
|
14
|
+
<%- end -%>
|
15
|
+
<%- else -%>
|
16
|
+
<%= k %> <%= v %>
|
17
|
+
<%- end -%>
|
18
|
+
<%- end %>
|
19
|
+
<%- end %>
|
data/nymphia.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nymphia/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'nymphia'
|
8
|
+
spec.version = Nymphia::VERSION
|
9
|
+
spec.authors = ['mozamimy (Moza USANE)']
|
10
|
+
spec.email = ['mozamimy@quellencode.org']
|
11
|
+
|
12
|
+
spec.summary = 'Create your SSH config without any pain.'
|
13
|
+
spec.description = 'Create your SSH config without any pain.'
|
14
|
+
spec.homepage = 'https://github.com/mozamimy/nymphia'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
|
28
|
+
spec.add_dependency 'activesupport', '~> 5.0.0.1'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nymphia
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mozamimy (Moza USANE)
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-13 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.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
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: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.0.0.1
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.0.0.1
|
69
|
+
description: Create your SSH config without any pain.
|
70
|
+
email:
|
71
|
+
- mozamimy@quellencode.org
|
72
|
+
executables:
|
73
|
+
- nymphia
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".ruby-version"
|
80
|
+
- ".travis.yml"
|
81
|
+
- Gemfile
|
82
|
+
- LICENSE.txt
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- bin/console
|
86
|
+
- bin/setup
|
87
|
+
- examples/base.rb
|
88
|
+
- examples/company.rb
|
89
|
+
- examples/result.example
|
90
|
+
- exe/nymphia
|
91
|
+
- lib/nymphia.rb
|
92
|
+
- lib/nymphia/cli.rb
|
93
|
+
- lib/nymphia/dsl.rb
|
94
|
+
- lib/nymphia/dsl/context.rb
|
95
|
+
- lib/nymphia/dsl/context/default_params.rb
|
96
|
+
- lib/nymphia/dsl/context/gateway.rb
|
97
|
+
- lib/nymphia/dsl/context/group.rb
|
98
|
+
- lib/nymphia/dsl/context/host.rb
|
99
|
+
- lib/nymphia/dsl/context/host_context_methods.rb
|
100
|
+
- lib/nymphia/dsl/context/proxy.rb
|
101
|
+
- lib/nymphia/dsl/context/use_gateway.rb
|
102
|
+
- lib/nymphia/dsl/recursive_methods.rb
|
103
|
+
- lib/nymphia/ssh_config_template.erb
|
104
|
+
- lib/nymphia/version.rb
|
105
|
+
- nymphia.gemspec
|
106
|
+
homepage: https://github.com/mozamimy/nymphia
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.5.1
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Create your SSH config without any pain.
|
130
|
+
test_files: []
|