keyman 1.0.0 → 1.1.1
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.
- data/Gemfile.lock +3 -1
- data/README.md +43 -11
- data/bin/keyman +25 -6
- data/keyman.gemspec +1 -0
- data/lib/keyman.rb +84 -25
- data/lib/keyman/group.rb +3 -0
- data/lib/keyman/manifest.rb +77 -0
- data/lib/keyman/server.rb +45 -11
- data/lib/keyman/server_group.rb +29 -0
- data/lib/keyman/user.rb +4 -0
- data/templates/servers.km +22 -0
- data/templates/users.km +8 -0
- metadata +22 -3
- data/lib/keyman/keyfile.rb +0 -19
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -4,10 +4,6 @@ This simple little utility allows you to manage the authorized_keys files for a
|
|
4
4
|
number of servers & users. It is designed to provide easy access to ensure that
|
5
5
|
you can revoke & grant access to appropriate people on multiple servers.
|
6
6
|
|
7
|
-
**Please Note: this utility is somewhat un-tested and not currently used in any
|
8
|
-
production environment. Your mileage may vary and we recommend testing in a
|
9
|
-
non-production environment prior to use.**
|
10
|
-
|
11
7
|
## Installation
|
12
8
|
|
13
9
|
To install, just install the Rubygem.
|
@@ -17,12 +13,19 @@ $ gem install keyman
|
|
17
13
|
```
|
18
14
|
|
19
15
|
Once installed, you will need to create yourself a **manifest directory**. This
|
20
|
-
directory will contain all your configuration for your key manager. You
|
21
|
-
|
16
|
+
directory will contain all your configuration for your key manager. You can easily
|
17
|
+
do this using the `init` command:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
$ keyman init path/to/manifest
|
21
|
+
```
|
22
|
+
|
23
|
+
This will create a directory containing two files, a `users.km` and a `servers.km`.
|
24
|
+
These files contain examples and comments which should help you get started.
|
22
25
|
|
23
26
|
## Example Users/Groups Manifest File
|
24
27
|
|
25
|
-
The below file is an example of a `users.
|
28
|
+
The below file is an example of a `users.km` manifest file.
|
26
29
|
|
27
30
|
```ruby
|
28
31
|
group :admins do
|
@@ -39,7 +42,7 @@ end
|
|
39
42
|
|
40
43
|
## Example Server Manifest File
|
41
44
|
|
42
|
-
The below file is an example of a `servers.
|
45
|
+
The below file is an example of a `servers.km` file.
|
43
46
|
|
44
47
|
```ruby
|
45
48
|
# An example configuration for a server where all admin users have
|
@@ -56,13 +59,30 @@ server do
|
|
56
59
|
host 'database01.myapplication.com'
|
57
60
|
user 'root', :admins, :dan
|
58
61
|
end
|
62
|
+
|
63
|
+
# An example of a group of servers each with the same permissions. These
|
64
|
+
# will create servers with the same
|
65
|
+
server_group :load_balancers do
|
66
|
+
host 'lb01.myapplication.com'
|
67
|
+
host 'lb02.myapplication.com'
|
68
|
+
host 'lb03.myapplication.com'
|
69
|
+
user 'root', :admins
|
70
|
+
user 'app', :admins, :staff
|
71
|
+
end
|
59
72
|
```
|
60
73
|
|
74
|
+
You may add as many `.km` files as you wish to to your manifest directory and they
|
75
|
+
will be loaded. However, all **users** should be defined in `users.km` and nowhere
|
76
|
+
else.
|
77
|
+
|
61
78
|
## Pushing files to servers
|
62
79
|
|
63
|
-
In order to push files to
|
64
|
-
|
65
|
-
|
80
|
+
In order to push your authorized_keys files to your servers, keyman must be able
|
81
|
+
to authenticate. In the first instance, we will attempt to use your local SSH keys
|
82
|
+
to do this. If we cannot authenticate with these, you will be prompted for the password
|
83
|
+
when you attempt to push. This password, if accepted, will then be cached for your
|
84
|
+
"session" and attempted for any subsequent servers which cannot be authenticated with
|
85
|
+
your SSH keys.
|
66
86
|
|
67
87
|
```bash
|
68
88
|
$ cd path/to/manifest
|
@@ -70,6 +90,8 @@ $ cd path/to/manifest
|
|
70
90
|
$ keyman push
|
71
91
|
# to push configuration to a specific server
|
72
92
|
$ keyman push database01.myapplication.com
|
93
|
+
# to push configuration to a server group
|
94
|
+
$ keyman push load_balancers
|
73
95
|
```
|
74
96
|
|
75
97
|
There are other commands available within the app, you can view these by
|
@@ -78,3 +100,13 @@ viewing the inline help.
|
|
78
100
|
```bash
|
79
101
|
$ keyman help
|
80
102
|
```
|
103
|
+
|
104
|
+
## Storing your manifest directory
|
105
|
+
|
106
|
+
It is recommended to store your manifest directory in a Git repository. Once in a
|
107
|
+
repository, you will be required to ensure that your local branch is always the same
|
108
|
+
as your remote branch before you can push to a server. This ensures that you cannot
|
109
|
+
overwrite someone elses changes should you forget to pull before pushing.
|
110
|
+
|
111
|
+
This behaviour is automatic and currently non-optional when there is a .git directory
|
112
|
+
in your manifest.
|
data/bin/keyman
CHANGED
@@ -22,17 +22,36 @@ begin
|
|
22
22
|
puts "commands. In order to use this, you must be currently within your"
|
23
23
|
puts "manifest directory."
|
24
24
|
puts
|
25
|
-
puts "
|
26
|
-
puts "
|
27
|
-
puts "
|
28
|
-
puts "
|
29
|
-
puts "
|
30
|
-
puts "
|
25
|
+
puts " init {path} - creates a new manifest directory"
|
26
|
+
puts " keys {server} {user} - displays the authorized keys file for a server's user"
|
27
|
+
puts " push - pushes the latest files to all servers"
|
28
|
+
puts " push {server} - pushes the latest file to the specified server"
|
29
|
+
puts " servers - displays a list of all servers"
|
30
|
+
puts " permissions {server} - displays the permissions for given server"
|
31
|
+
puts " users - displays a list of all users & groups"
|
31
32
|
puts
|
33
|
+
when 'init'
|
34
|
+
require 'fileutils'
|
35
|
+
if path = final_args[1]
|
36
|
+
if File.exist?(path)
|
37
|
+
raise Keyman::Error, "A file/directory already exists at #{path}"
|
38
|
+
else
|
39
|
+
FileUtils.mkdir(path)
|
40
|
+
template_root = File.expand_path(File.join('..', '..', 'templates'), __FILE__)
|
41
|
+
File.open(File.join(path, 'users.km'), 'w') { |f| f.write(File.read(File.join(template_root, 'users.km')))}
|
42
|
+
File.open(File.join(path, 'servers.km'), 'w') { |f| f.write(File.read(File.join(template_root, 'servers.km')))}
|
43
|
+
puts "\e[32mKeyman manifest directory created at #{path} successfully.\e[0m"
|
44
|
+
end
|
45
|
+
else
|
46
|
+
raise Keyman::Error, "You should pass a directory name to the init command to create a new manifest directory."
|
47
|
+
end
|
32
48
|
else
|
49
|
+
puts "\e[37mUsing manifest from #{Keyman.manifest_dir}\e[0m"
|
33
50
|
Keyman.run(final_args, options)
|
34
51
|
end
|
35
52
|
|
53
|
+
rescue SystemExit, Interrupt
|
54
|
+
Process.exit(0)
|
36
55
|
rescue Keyman::Error => e
|
37
56
|
puts "\e[31m" + e.message + "\e[0m"
|
38
57
|
Process.exit(1)
|
data/keyman.gemspec
CHANGED
data/lib/keyman.rb
CHANGED
@@ -1,45 +1,55 @@
|
|
1
|
+
require 'yaml'
|
1
2
|
require 'net/ssh'
|
3
|
+
require 'highline/import'
|
2
4
|
|
3
5
|
require 'keyman/user'
|
4
6
|
require 'keyman/group'
|
5
7
|
require 'keyman/server'
|
6
|
-
require 'keyman/
|
7
|
-
|
8
|
+
require 'keyman/server_group'
|
9
|
+
require 'keyman/manifest'
|
8
10
|
|
9
11
|
module Keyman
|
10
12
|
|
11
13
|
# The current version of the keyman system
|
12
|
-
VERSION = '1.
|
14
|
+
VERSION = '1.1.1'
|
13
15
|
|
14
16
|
# An error which will be raised
|
15
17
|
class Error < StandardError; end
|
16
18
|
|
17
19
|
class << self
|
20
|
+
# Stores the actual manifest object
|
21
|
+
attr_accessor :manifest
|
22
|
+
|
23
|
+
# Storage for the manifest directory to work with
|
24
|
+
attr_accessor :manifest_dir
|
25
|
+
|
18
26
|
# Storage for all the users, groups & servers which are loaded
|
19
27
|
# from the manifest
|
20
28
|
attr_accessor :users
|
21
29
|
attr_accessor :groups
|
22
30
|
attr_accessor :servers
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
attr_accessor :server_groups
|
32
|
+
|
33
|
+
# Storage for a password cache to use within the current session
|
34
|
+
attr_accessor :password_cache
|
35
|
+
|
36
|
+
# Sets the default manifest_dir dir
|
37
|
+
def manifest_dir
|
38
|
+
@manifest_dir || self.config['manifest_dir'] || "./"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sets the configuration options
|
42
|
+
def config
|
43
|
+
@config ||= begin
|
44
|
+
config_dir = File.join(ENV['HOME'], '.keyman')
|
45
|
+
if File.exist?(config_dir)
|
46
|
+
YAML.load_file(config_dir)
|
47
|
+
else
|
48
|
+
{}
|
37
49
|
end
|
38
|
-
else
|
39
|
-
raise Error, "No folder found at '#{directory}'"
|
40
50
|
end
|
41
51
|
end
|
42
|
-
|
52
|
+
|
43
53
|
# Return a user or a group for the given name
|
44
54
|
def user_or_group_for(name)
|
45
55
|
self.users.select { |u| u.name == name.to_sym }.first || self.groups.select { |u| u.name == name.to_sym }.first
|
@@ -47,7 +57,7 @@ module Keyman
|
|
47
57
|
|
48
58
|
# Execute a CLI command
|
49
59
|
def run(args, options = {})
|
50
|
-
load
|
60
|
+
Manifest.load
|
51
61
|
case args.first
|
52
62
|
when 'keys'
|
53
63
|
if server = self.servers.select { |s| s.host == args[1] }.first
|
@@ -73,10 +83,26 @@ module Keyman
|
|
73
83
|
raise Error, "No server found with the hostname '#{args[1]}'"
|
74
84
|
end
|
75
85
|
when 'push'
|
86
|
+
|
87
|
+
if self.manifest.uses_git?
|
88
|
+
unless self.manifest.clean?
|
89
|
+
raise Error, "Your manifest is not clean. You should push to your repository before pushing."
|
90
|
+
end
|
91
|
+
|
92
|
+
unless self.manifest.latest_commit?
|
93
|
+
raise Error, "The remote server has a more up-to-date manifest. Pull first."
|
94
|
+
end
|
95
|
+
|
96
|
+
puts "\e[32mRepository check passed!\e[0m"
|
97
|
+
end
|
98
|
+
|
76
99
|
if args[1]
|
77
|
-
|
78
|
-
|
100
|
+
server = self.servers.select { |s| s.host == args[1] }.first
|
101
|
+
server = self.server_groups.select { |s| s.name == args[1].to_sym }.first if server.nil?
|
102
|
+
if server.is_a?(Keyman::Server)
|
79
103
|
server.push!
|
104
|
+
elsif server.is_a?(Keyman::ServerGroup)
|
105
|
+
server.servers.each(&:push!)
|
80
106
|
else
|
81
107
|
raise Error, "No server found with the hostname '#{args[1]}'"
|
82
108
|
end
|
@@ -84,9 +110,21 @@ module Keyman
|
|
84
110
|
self.servers.each(&:push!)
|
85
111
|
end
|
86
112
|
when 'servers'
|
87
|
-
self.
|
88
|
-
puts
|
113
|
+
self.server_groups.sort_by(&:name).each do |group|
|
114
|
+
puts '-' * 80
|
115
|
+
puts group.name.to_s
|
116
|
+
puts '-' * 80
|
117
|
+
group.servers.each do |s|
|
118
|
+
puts " * #{s.host}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
puts '-' * 80
|
122
|
+
puts 'no group'
|
123
|
+
puts '-' * 80
|
124
|
+
self.servers.select { |s| s.group.nil?}.each do |s|
|
125
|
+
puts " * #{s.host}"
|
89
126
|
end
|
127
|
+
|
90
128
|
when 'users'
|
91
129
|
self.groups.each do |group|
|
92
130
|
puts "-" * 80
|
@@ -97,6 +135,27 @@ module Keyman
|
|
97
135
|
puts "\e[37m#{u.key}\e[0m"
|
98
136
|
end
|
99
137
|
end
|
138
|
+
|
139
|
+
when 'status'
|
140
|
+
if Keyman.manifest.uses_git?
|
141
|
+
puts "Your manifest is using a remote git repository."
|
142
|
+
if Keyman.manifest.clean?
|
143
|
+
puts " * Your working copy is clean"
|
144
|
+
else
|
145
|
+
puts " * You have an un-clean working copy. You must commit before pushing."
|
146
|
+
end
|
147
|
+
|
148
|
+
if Keyman.manifest.latest_commit?
|
149
|
+
puts " * You have the latest commit fetched."
|
150
|
+
else
|
151
|
+
puts " * There is a newer version of this repo on the server."
|
152
|
+
end
|
153
|
+
else
|
154
|
+
puts "Your manifest does not use git. There is no status to display."
|
155
|
+
end
|
156
|
+
|
157
|
+
else
|
158
|
+
raise Error, "Invalid command '#{args.first}'"
|
100
159
|
end
|
101
160
|
end
|
102
161
|
end
|
data/lib/keyman/group.rb
CHANGED
@@ -9,6 +9,9 @@ module Keyman
|
|
9
9
|
|
10
10
|
# Add a new group with the given name
|
11
11
|
def self.add(name, &block)
|
12
|
+
if existing = Keyman.user_or_group_for(name)
|
13
|
+
raise Error, "#{existing.class.to_s.split('::').last} already exists for '#{name}' - cannot define user with this name."
|
14
|
+
end
|
12
15
|
g = Group.new
|
13
16
|
g.name = name
|
14
17
|
g.instance_eval(&block)
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Keyman
|
2
|
+
class Manifest
|
3
|
+
|
4
|
+
# Loads a manifest directory as live
|
5
|
+
def self.load(directory = Keyman.manifest_dir)
|
6
|
+
Keyman.users = []
|
7
|
+
Keyman.groups = []
|
8
|
+
Keyman.servers = []
|
9
|
+
Keyman.server_groups = []
|
10
|
+
manifest = self.new(directory)
|
11
|
+
if File.directory?(directory)
|
12
|
+
[File.join(directory, 'users.km'), Dir[File.join(directory, '*.km')]].flatten.uniq.compact.each do |file|
|
13
|
+
if File.exist?(file)
|
14
|
+
manifest.instance_eval(File.read(file))
|
15
|
+
else
|
16
|
+
raise Error, "No '#{file}' was found in your manifest directory. Abandoning..."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
Keyman.manifest = manifest
|
20
|
+
else
|
21
|
+
raise Error, "No folder found at '#{directory}'"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Initialize a new manifest with the current directory
|
26
|
+
def initialize(directory)
|
27
|
+
@directory = directory
|
28
|
+
end
|
29
|
+
|
30
|
+
# Adds a new group
|
31
|
+
def group(name, &users_block)
|
32
|
+
Group.add(name, &users_block)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Adds a new server
|
36
|
+
def server(&block)
|
37
|
+
Server.add(&block)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Adds a new user
|
41
|
+
def user(username, key)
|
42
|
+
User.add(username, key)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds a new server group
|
46
|
+
def server_group(name, &block)
|
47
|
+
ServerGroup.add(name, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Does this manifest directory use git?
|
51
|
+
def uses_git?
|
52
|
+
File.directory?(File.join(@directory, '.git'))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Is the current repo clean?
|
56
|
+
def clean?
|
57
|
+
`cd #{@directory} && git status`.chomp.include?('nothing to commit')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Does the latest commit on the current branch match the remote brandh
|
61
|
+
def latest_commit?
|
62
|
+
local = `cd #{@directory} && git log --pretty=%H -n 1`.chomp
|
63
|
+
if `cd #{@directory} && git status`.chomp.match(/On branch (.*)\n/)
|
64
|
+
branch = $1
|
65
|
+
else
|
66
|
+
raise Error, "Unable to determine the local repository branch."
|
67
|
+
end
|
68
|
+
remote = `cd #{@directory} && git ls-remote 2> /dev/null | grep refs/heads/#{branch} `.chomp.split(/\s+/).first
|
69
|
+
if local.length == 40 && remote.length == 40
|
70
|
+
local == remote
|
71
|
+
else
|
72
|
+
raise Error, "Unable to determine local & remote commits"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
data/lib/keyman/server.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Keyman
|
2
2
|
class Server
|
3
3
|
|
4
|
-
attr_accessor :host, :users, :location
|
4
|
+
attr_accessor :host, :users, :location, :group
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@users = {}
|
@@ -15,6 +15,17 @@ module Keyman
|
|
15
15
|
s
|
16
16
|
end
|
17
17
|
|
18
|
+
# Adds a new server based on it's name and location
|
19
|
+
def self.add_by_name(host, options = {})
|
20
|
+
s = self.new
|
21
|
+
s.host = host
|
22
|
+
s.location = options[:location]
|
23
|
+
s.users = options[:users]
|
24
|
+
s.group = options[:group]
|
25
|
+
Keyman.servers << s
|
26
|
+
s
|
27
|
+
end
|
28
|
+
|
18
29
|
# Returns or sets the hostname of the server which should be used when connecting
|
19
30
|
# and identifying this server
|
20
31
|
def host(host = nil)
|
@@ -24,6 +35,7 @@ module Keyman
|
|
24
35
|
# Sets a user on the server along with the access objects which should be
|
25
36
|
# granted access
|
26
37
|
def user(name, *access_objects)
|
38
|
+
access_objects.each { |ao| raise Error, "!! Invalid access object '#{ao}' on '#{self.host}'" unless Keyman.user_or_group_for(ao) }
|
27
39
|
@users[name] = access_objects
|
28
40
|
end
|
29
41
|
|
@@ -36,9 +48,12 @@ module Keyman
|
|
36
48
|
# all objects from within the server
|
37
49
|
def authorized_users(username)
|
38
50
|
@users[username].map do |k|
|
39
|
-
obj = Keyman.user_or_group_for(k)
|
40
|
-
|
41
|
-
|
51
|
+
if obj = Keyman.user_or_group_for(k)
|
52
|
+
obj.is_a?(Group) ? obj.users : obj
|
53
|
+
else
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end.flatten.compact.uniq
|
42
57
|
end
|
43
58
|
|
44
59
|
# Returns a full string output for the authorized_keys file. Passes
|
@@ -59,20 +74,39 @@ module Keyman
|
|
59
74
|
# configured here. This will not succeed if the current user does not
|
60
75
|
# already have a key on the server.
|
61
76
|
def push!
|
77
|
+
passwords_to_try = (Keyman.password_cache ||= [nil]).dup
|
62
78
|
@users.each do |user, objects|
|
63
79
|
begin
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
80
|
+
passwords_to_try.each do |password|
|
81
|
+
Timeout.timeout(10) do |t|
|
82
|
+
Net::SSH.start(self.host, user, :password => password) do |ssh|
|
83
|
+
ssh.exec!("mkdir -p ~/.ssh")
|
84
|
+
file = authorized_keys(user).gsub("\n", "\\n").gsub("\t", "\\t")
|
85
|
+
ssh.exec!("echo -e '#{file}' > ~/.ssh/authorized_keys")
|
86
|
+
end
|
87
|
+
Keyman.password_cache << password if password
|
69
88
|
end
|
70
89
|
end
|
71
90
|
puts "\e[32mPushed authorized_keys to #{user}@#{self.host}\e[0m"
|
91
|
+
rescue Net::SSH::AuthenticationFailed
|
92
|
+
passwords_to_try.shift
|
93
|
+
if passwords_to_try.empty?
|
94
|
+
puts "\e[35mAuthorization failed on to #{user}@#{self.host}.\e[0m"
|
95
|
+
password = HighLine.ask("Enter password: ") { |q| q.echo = "*" }
|
96
|
+
if password.length > 0
|
97
|
+
passwords_to_try << password
|
98
|
+
retry
|
99
|
+
else
|
100
|
+
puts "\e[37mSkipping #{user}@#{self.host}\e[0m"
|
101
|
+
end
|
102
|
+
else
|
103
|
+
retry
|
104
|
+
end
|
72
105
|
rescue Timeout::Error
|
73
106
|
puts "\e[31mTimed out while uploading authorized_keys to #{user}@#{self.host}\e[0m"
|
74
|
-
rescue
|
75
|
-
puts "\e[31mFailed to upload authorized_keys to #{user}@#{self.host}\e[0m"
|
107
|
+
rescue => e
|
108
|
+
puts "\e[31mFailed to upload authorized_keys to #{user}@#{self.host} (#{e.class})\e[0m"
|
109
|
+
puts e.message
|
76
110
|
end
|
77
111
|
end
|
78
112
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Keyman
|
2
|
+
class ServerGroup
|
3
|
+
|
4
|
+
attr_accessor :servers, :users, :name
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@servers = []
|
8
|
+
@users = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.add(name, &block)
|
12
|
+
s = self.new
|
13
|
+
s.name = name
|
14
|
+
s.instance_eval(&block)
|
15
|
+
Keyman.server_groups << s
|
16
|
+
s
|
17
|
+
end
|
18
|
+
|
19
|
+
def server(host, location = nil)
|
20
|
+
@servers << Server.add_by_name(host, :users => @users, :group => self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def user(name, *access_objects)
|
24
|
+
@users[name] = access_objects
|
25
|
+
@servers.each { |s| s.user(name, *access_objects) }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/keyman/user.rb
CHANGED
@@ -9,6 +9,10 @@ module Keyman
|
|
9
9
|
if existing
|
10
10
|
existing
|
11
11
|
else
|
12
|
+
if existing = Keyman.user_or_group_for(name)
|
13
|
+
raise Error, "#{existing.class.to_s.split('::').last} already exists for '#{name}' - cannot define user with this name."
|
14
|
+
end
|
15
|
+
|
12
16
|
u = self.new
|
13
17
|
u.name = name.to_sym
|
14
18
|
u.key = key
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Example Keyman server configuration file
|
2
|
+
# This file should contain all your server & server group definitions which should
|
3
|
+
# be used within this manifest.
|
4
|
+
#
|
5
|
+
# You may also create other files with the extension .km within your manifest directory.
|
6
|
+
# These must only contain server/server group definitions.
|
7
|
+
#
|
8
|
+
# server_group :app_servers do
|
9
|
+
# server 'app01.myapplication.com'
|
10
|
+
# server 'app02.myapplication.com'
|
11
|
+
# server 'app03.myapplication.com'
|
12
|
+
#
|
13
|
+
# user 'root', :admins
|
14
|
+
# user 'app', :admins, :staff
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# server do
|
18
|
+
# host 'db-a.myapplication.com'
|
19
|
+
# location :london
|
20
|
+
# user 'root', :admins
|
21
|
+
# user 'db', :admins, :database_admins
|
22
|
+
# end
|
data/templates/users.km
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keyman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01
|
12
|
+
date: 2013-02-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-ssh
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 2.6.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: highline
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
description: A simple library for managing distributed SSH keys
|
31
47
|
email: adam@atechmedia.com
|
32
48
|
executables:
|
@@ -39,11 +55,14 @@ files:
|
|
39
55
|
- Gemfile.lock
|
40
56
|
- keyman.gemspec
|
41
57
|
- lib/keyman/group.rb
|
42
|
-
- lib/keyman/
|
58
|
+
- lib/keyman/manifest.rb
|
43
59
|
- lib/keyman/server.rb
|
60
|
+
- lib/keyman/server_group.rb
|
44
61
|
- lib/keyman/user.rb
|
45
62
|
- lib/keyman.rb
|
46
63
|
- README.md
|
64
|
+
- templates/servers.km
|
65
|
+
- templates/users.km
|
47
66
|
homepage: http://atechmedia.com
|
48
67
|
licenses: []
|
49
68
|
post_install_message:
|
data/lib/keyman/keyfile.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
module Keyman
|
2
|
-
class Keyfile
|
3
|
-
|
4
|
-
class << self
|
5
|
-
def group(name, &users_block)
|
6
|
-
Group.add(name, &users_block)
|
7
|
-
end
|
8
|
-
|
9
|
-
def server(&block)
|
10
|
-
Server.add(&block)
|
11
|
-
end
|
12
|
-
|
13
|
-
def user(username, key)
|
14
|
-
User.add(username, key)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|