zanzibar 0.1.13 → 0.1.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +3 -0
- data/.rspec +1 -1
- data/.rubocop.yml +5 -0
- data/Gemfile +0 -13
- data/README.md +68 -6
- data/Rakefile +11 -11
- data/bin/zamioculcas +3 -1
- data/bin/zanzibar +2 -68
- data/lib/zanzibar/actions/base.rb +27 -0
- data/lib/zanzibar/actions/bundle.rb +119 -0
- data/lib/zanzibar/actions/get.rb +61 -0
- data/lib/zanzibar/actions/init.rb +40 -0
- data/lib/zanzibar/actions.rb +3 -0
- data/lib/zanzibar/cli.rb +126 -0
- data/lib/zanzibar/defaults.rb +14 -0
- data/lib/zanzibar/error.rb +6 -0
- data/lib/zanzibar/ui.rb +42 -0
- data/lib/zanzibar/version.rb +4 -3
- data/lib/zanzibar.rb +190 -190
- data/spec/files/.gitignore +1 -0
- data/spec/files/Zanzifile +11 -0
- data/spec/files/scrt.wsdl +629 -0
- data/spec/lib/zanzibar/actions/bundle_spec.rb +95 -0
- data/spec/lib/zanzibar/actions/get_spec.rb +64 -0
- data/spec/lib/zanzibar/actions/init_spec.rb +53 -0
- data/spec/lib/zanzibar/version_spec.rb +12 -0
- data/spec/{zanzibar_spec.rb → lib/zanzibar_spec.rb} +116 -123
- data/spec/spec_helper.rb +37 -0
- data/templates/Zanzifile.erb +11 -0
- data/zanzibar.gemspec +12 -4
- metadata +142 -19
- data/spec/spec/spec_helper.rb +0 -95
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODVkZWYyOTM0OWZkZjkzNTBjNmNkOWJkNThiYzRkNTc1MGQ4YjJlZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NWJlM2NhM2ZiMWMzMGVjZmQ4YWVkNGY5MjVhODVlMjY5MTVjZTRjNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjVmNDdiMmVhZTA0MDg5MTNhNWM0OWM2ZTQyMWViNmE5ZjJmNGFkMjIxOWVi
|
10
|
+
Y2FjYjlkYzcyMWUzOGJhMmExOGY3MTljMWZkOTI1ZGEzZWE0Yjc1ZDU5NDE0
|
11
|
+
NDg5YWFkNTllOWNlZDkwNmRlNGI3MTRkNjFhY2QwNWQ2YjMxMGI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmMwZGYyZGZlODEzMjkyN2UxZTc2YzhiMjAzZGZjN2M2OGI2OGZmMWY0ZThl
|
14
|
+
MjdlZjQ4NDc3OWRkMGZkYTNkYjEwM2ZhYWE1ZDkxOTI0YjdkNGNlZGE5N2Zh
|
15
|
+
NDgxOGNkM2I4NTAwZDc0ZGViYWQ4NjZkZGI5MjM4NDMzMDM0ODc=
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--require
|
2
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
@@ -1,16 +1,3 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'savon'
|
4
|
-
|
5
|
-
group :test do
|
6
|
-
gem 'rake'
|
7
|
-
gem 'savon_spec'
|
8
|
-
gem 'rspec'
|
9
|
-
gem 'webmock'
|
10
|
-
gem 'codeclimate-test-reporter'
|
11
|
-
gem 'zanzibar', path: '.'
|
12
|
-
gem 'rubocop'
|
13
|
-
end
|
14
|
-
|
15
|
-
# Specify your gem's dependencies in zanzibar.gemspec
|
16
3
|
gemspec
|
data/README.md
CHANGED
@@ -21,7 +21,11 @@ Or install it yourself as:
|
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
24
|
-
In your ruby project, rakefile, etc., create a new Zanzibar object.
|
24
|
+
In your ruby project, rakefile, etc., create a new Zanzibar object.
|
25
|
+
|
26
|
+
The constructor takes a hash of optional parameters for the WSDL location, the domain of the Secret Server, a hash of global variables to pass to savon (necessary for windows environments with self-signed certs) and a password for the current user (intended to be passed in through some encryption method, unless you really want a plaintext password there).
|
27
|
+
|
28
|
+
All of these parameters are optional and the user will be prompted to enter them if they are missing.
|
25
29
|
|
26
30
|
```ruby
|
27
31
|
my_object = Zanzibar::Zanzibar.new(:domain => 'my.domain.net', :wsdl => 'my.scrt.srvr.com/webservices/sswebservice.asmx?wdsl', :pwd => get_encrypted_password_from_somewhere)
|
@@ -51,20 +55,78 @@ secrets.download_secret_file(:scrt_id => 2345, :path => 'secrets/', :type => "At
|
|
51
55
|
|
52
56
|
```
|
53
57
|
|
58
|
+
### Providing Credentials
|
59
|
+
|
60
|
+
Zanzibar has several ways of finding Secret Server credentials. It will use credentials
|
61
|
+
discovered in this order:
|
62
|
+
|
63
|
+
* Credentials passed to the initializer
|
64
|
+
* `Zanzibar::Zanzibar.new(:username=>'auser', :password=>'itsmyPassword')`
|
65
|
+
* Credentials discovered via the environment
|
66
|
+
* If `ZANZIBAR_USER` exists, it will use that.
|
67
|
+
* If not, it will try `USER`
|
68
|
+
* If `ZANZIBAR_PASSWORD` exists, it will use that.
|
69
|
+
* Credentials entered by the user
|
70
|
+
* Zanzibar will prompt the user to enter their password on STDIN
|
71
|
+
|
54
72
|
### Command Line
|
55
73
|
|
56
|
-
Zanzibar comes bundled with the `zanzibar` command-line utility that can be used
|
74
|
+
Zanzibar comes bundled with the `zanzibar` command-line utility that can be used
|
75
|
+
for fetching passwords and downloading keys from outside of Ruby scripts.
|
57
76
|
|
58
|
-
`zanzibar` supports most actions provided by Zanzibar itself. Because it operates
|
77
|
+
`zanzibar` supports most actions provided by Zanzibar itself. Because it operates
|
78
|
+
on the command-line, it can be used as part of a pipeline or within a bash script.
|
59
79
|
|
60
80
|
```bash
|
61
|
-
# if
|
81
|
+
# if ZANZIBAR_PASSWORD is not set, you will be prompted to enter your password.
|
62
82
|
# this will download the private key from secret 1984 to the current directory
|
63
|
-
|
83
|
+
$ ZANZIBAR_PASSWORD=`gpg -d secretpasswd.txt.gpg` zanzibar get 1984 -s server.example.com -d example.com -f "Private Key"
|
84
|
+
|
85
|
+
$ ssh user@someremote -i ./private_key
|
86
|
+
```
|
64
87
|
|
65
|
-
|
88
|
+
#### Zanzifiles
|
89
|
+
|
90
|
+
The `zanzibar` command can also perform [bundler](http://bundler.io)-like actions.
|
91
|
+
Running `zanzibar init` will generate a `Zanzifile` in the current directory.
|
92
|
+
Information about Secret Server and the necessary secret files to be downloaded
|
93
|
+
can be added here.
|
94
|
+
|
95
|
+
Then `zanzibar bundle` will try to download the secrets named in the file.
|
96
|
+
When it downloads a file, it gets added to `Zanzifile.resolved`. And next time
|
97
|
+
`zanzibar bundle` is run, if the file exists and the hash matches the one in the
|
98
|
+
`resolved` file, it will not attempt to re-download. `zanzibar update` will attempt
|
99
|
+
to re-download all secrets.
|
100
|
+
|
101
|
+
Note: `zanzibar get` can fetch passwords or files, but `zanzibar bundle` can
|
102
|
+
only operate on secret files.
|
103
|
+
|
104
|
+
Sample `Zanzifile`:
|
105
|
+
|
106
|
+
```yaml
|
107
|
+
---
|
108
|
+
settings:
|
109
|
+
wsdl: my.scrt.srvr.com/webservices/sswebservice.asmx?wdsl
|
110
|
+
domain: my.domain.net
|
111
|
+
secret_dir: secrets/
|
112
|
+
ignore_ssl: true
|
113
|
+
secrets:
|
114
|
+
ssh_key:
|
115
|
+
id: 249
|
116
|
+
label: Private Key
|
117
|
+
encryption_key:
|
118
|
+
id: 483
|
119
|
+
label: Attachment
|
120
|
+
cert_pem:
|
121
|
+
id: 123
|
122
|
+
label: Certificate
|
123
|
+
cert_key:
|
124
|
+
id: 986
|
125
|
+
label: Misc Attachment
|
66
126
|
```
|
67
127
|
|
128
|
+
Run `zanzibar help` or `zanzibar help [command]` for more information.
|
129
|
+
|
68
130
|
## Contributing
|
69
131
|
|
70
132
|
1. Fork it ( https://github.com/Cimpress-MCP/zanzibar/fork )
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'bundler/setup' # load up our gem environment (incl. local zanzibar)
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
require 'zanzibar/version'
|
5
|
-
require 'rubocop/rake_task'
|
6
|
-
|
7
|
-
task default: [:test]
|
8
|
-
|
9
|
-
RSpec::Core::RakeTask.new(:test)
|
10
|
-
|
11
|
-
RuboCop::RakeTask.new
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'bundler/setup' # load up our gem environment (incl. local zanzibar)
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require 'zanzibar/version'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
|
7
|
+
task default: [:test]
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:test)
|
10
|
+
|
11
|
+
RuboCop::RakeTask.new
|
data/bin/zamioculcas
CHANGED
data/bin/zanzibar
CHANGED
@@ -1,70 +1,4 @@
|
|
1
1
|
#! ruby
|
2
|
+
require 'zanzibar/cli'
|
2
3
|
|
3
|
-
|
4
|
-
require 'optparse'
|
5
|
-
|
6
|
-
options = {
|
7
|
-
:domain => 'local'
|
8
|
-
}
|
9
|
-
|
10
|
-
OptionParser.new do |opts|
|
11
|
-
opts.banner = "Usage: zamioculcas -d domain [-w wsdl] [-k] [-p] [secret_id]"
|
12
|
-
|
13
|
-
opts.on("-d", "--domain DOMAIN", "Specify domain") do |v|
|
14
|
-
options[:domain] = v
|
15
|
-
end
|
16
|
-
|
17
|
-
opts.on("-w", "--wsdl WSDL", "Specify WSDL location") do |v|
|
18
|
-
options[:wsdl] = v
|
19
|
-
end
|
20
|
-
|
21
|
-
opts.on("-s", "--server SERVER", "Secret server hostname or IP") do |v|
|
22
|
-
options[:server] = v
|
23
|
-
end
|
24
|
-
|
25
|
-
opts.on("-k", "--no-check-certificate", "Don't run SSL certificate checks") do |v|
|
26
|
-
options[:globals] = {:ssl_verify_mode => :none}
|
27
|
-
end
|
28
|
-
|
29
|
-
opts.on("-p", "--password PASSWORD", "Specify password") do |v|
|
30
|
-
options[:pwd] = v
|
31
|
-
end
|
32
|
-
|
33
|
-
opts.on("-t", "--type TYPE", "Specify the type of secret") do |v|
|
34
|
-
options[:type] = v
|
35
|
-
end
|
36
|
-
|
37
|
-
opts.on("-u", "--user USER", "Specify the username") do |v|
|
38
|
-
options[:username] = v
|
39
|
-
end
|
40
|
-
|
41
|
-
end.parse!
|
42
|
-
|
43
|
-
raise OptionParser::MissingArgument if options[:server].nil?
|
44
|
-
options[:type] = "password" if options[:type].nil?
|
45
|
-
|
46
|
-
unless STDIN.tty? || options[:pwd]
|
47
|
-
options[:pwd] = $stdin.read.strip
|
48
|
-
end
|
49
|
-
|
50
|
-
secret_id = Integer(ARGV.pop)
|
51
|
-
if(!secret_id)
|
52
|
-
fail "no secret!"
|
53
|
-
end
|
54
|
-
|
55
|
-
unless options[:wsdl] || options[:server].nil?
|
56
|
-
options[:wsdl] = "https://#{options[:server]}/webservices/sswebservice.asmx?wsdl"
|
57
|
-
end
|
58
|
-
|
59
|
-
scrt = Zanzibar::Zanzibar.new(options)
|
60
|
-
|
61
|
-
case options[:type]
|
62
|
-
when "password"
|
63
|
-
$stdout.write "#{scrt.get_password(secret_id)}\n"
|
64
|
-
when "privatekey"
|
65
|
-
scrt.download_private_key(:scrt_id=>secret_id)
|
66
|
-
when "publickey"
|
67
|
-
scrt.download_public_key(:scrt_id=>secret_id)
|
68
|
-
else
|
69
|
-
$stderr.write "#{options[:type]} is not a known type."
|
70
|
-
end
|
4
|
+
Zanzibar::Cli.start(ARGV)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Zanzibar
|
2
|
+
module Actions
|
3
|
+
# Basic plumbing for all actions
|
4
|
+
class Base
|
5
|
+
attr_accessor :options
|
6
|
+
private :options=
|
7
|
+
|
8
|
+
attr_accessor :logger
|
9
|
+
private :logger=
|
10
|
+
|
11
|
+
def initialize(logger, options = {})
|
12
|
+
self.logger = logger
|
13
|
+
self.options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def debug(*args, &block)
|
19
|
+
logger.debug(*args, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def source_root
|
23
|
+
@source_root ||= Pathname.new(File.expand_path('../../../../', __FILE__))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'zanzibar/actions/base'
|
2
|
+
require 'zanzibar/error'
|
3
|
+
require 'zanzibar'
|
4
|
+
|
5
|
+
module Zanzibar
|
6
|
+
module Actions
|
7
|
+
# Download or verify the secrets in a Zanzifile
|
8
|
+
class Bundle < Base
|
9
|
+
attr_accessor :settings
|
10
|
+
attr_accessor :remote_secrets
|
11
|
+
attr_accessor :local_secrets
|
12
|
+
attr_accessor :update
|
13
|
+
attr_accessor :zanzibar
|
14
|
+
|
15
|
+
def initialize(ui, options, args = {})
|
16
|
+
super(ui, options)
|
17
|
+
@update = args[:update]
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
ensure_zanzifile
|
22
|
+
load_required_secrets
|
23
|
+
validate_environment
|
24
|
+
load_resolved_secrets if resolved_file?
|
25
|
+
validate_local_secrets unless @update
|
26
|
+
run!
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def run!
|
32
|
+
if need_secrets?
|
33
|
+
new_secrets = download_remote_secrets
|
34
|
+
update_resolved_file new_secrets
|
35
|
+
else
|
36
|
+
debug { 'No secrets to download...' }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def ensure_zanzifile
|
41
|
+
fail Error, NO_ZANZIFILE_ERROR unless File.exist? ZANZIFILE_NAME
|
42
|
+
debug { "#{ZANZIFILE_NAME} located..." }
|
43
|
+
end
|
44
|
+
|
45
|
+
def resolved_file?
|
46
|
+
File.exist? RESOLVED_NAME
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_required_secrets
|
50
|
+
zanzifile = YAML.load_file(ZANZIFILE_NAME)
|
51
|
+
@settings = zanzifile['settings'] || {}
|
52
|
+
@remote_secrets = zanzifile['secrets'] || {}
|
53
|
+
@local_secrets = {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate_environment
|
57
|
+
return unless @settings.empty? || @remote_secrets.empty?
|
58
|
+
fail Error, INVALID_ZANZIFILE_ERROR
|
59
|
+
end
|
60
|
+
|
61
|
+
def load_resolved_secrets
|
62
|
+
@local_secrets = YAML.load_file RESOLVED_NAME
|
63
|
+
end
|
64
|
+
|
65
|
+
def need_secrets?
|
66
|
+
!@remote_secrets.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_local_secrets
|
70
|
+
@local_secrets.each do |key, secret|
|
71
|
+
if File.exist?(secret[:path]) && secret[:hash] == Digest::MD5.file(secret[:path]).hexdigest
|
72
|
+
debug { "#{key} found locally, skipping download..." }
|
73
|
+
@remote_secrets.delete key
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def download_remote_secrets
|
79
|
+
args = @settings['ignore_ssl'] ? { ssl_verify_mode: :none } : {}
|
80
|
+
|
81
|
+
downloaded_secrets = {}
|
82
|
+
remote_secrets.each do |key, secret|
|
83
|
+
downloaded_secrets[key] = download_one_secret(secret['id'],
|
84
|
+
secret['label'],
|
85
|
+
@settings['secret_dir'],
|
86
|
+
args)
|
87
|
+
|
88
|
+
debug { "Downloaded secret: #{key} to #{path}..." }
|
89
|
+
end
|
90
|
+
|
91
|
+
downloaded_secrets
|
92
|
+
end
|
93
|
+
|
94
|
+
def download_one_secret(scrt_id, label, path, args)
|
95
|
+
path = zanzibar(args).download_secret_file(scrt_id: scrt_id,
|
96
|
+
type: label,
|
97
|
+
path: path)
|
98
|
+
|
99
|
+
{ path: path, hash: Digest::MD5.file(path).hexdigest }
|
100
|
+
end
|
101
|
+
|
102
|
+
def update_resolved_file(new_secrets)
|
103
|
+
@local_secrets.merge! new_secrets
|
104
|
+
|
105
|
+
File.open(RESOLVED_NAME, 'w') do |out|
|
106
|
+
YAML.dump(@local_secrets, out)
|
107
|
+
end
|
108
|
+
|
109
|
+
debug { 'Updated resolved file...' }
|
110
|
+
end
|
111
|
+
|
112
|
+
def zanzibar(args)
|
113
|
+
@zanzibar ||= ::Zanzibar::Zanzibar.new(wsdl: @settings['wsdl'],
|
114
|
+
domain: @settings['domain'],
|
115
|
+
globals: args)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'zanzibar/actions/base'
|
2
|
+
require 'zanzibar/error'
|
3
|
+
require 'zanzibar'
|
4
|
+
require 'zanzibar/defaults'
|
5
|
+
|
6
|
+
module Zanzibar
|
7
|
+
module Actions
|
8
|
+
# Fetch a single secret
|
9
|
+
class Get < Base
|
10
|
+
attr_accessor :zanibar_options
|
11
|
+
attr_accessor :scrt_id
|
12
|
+
|
13
|
+
def initialize(ui, options, scrt_id)
|
14
|
+
super(ui, options)
|
15
|
+
@scrt_id = scrt_id
|
16
|
+
@zanzibar_options = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
construct_options
|
21
|
+
ensure_options
|
22
|
+
|
23
|
+
fetch_secret(@scrt_id, options['filelabel'])
|
24
|
+
end
|
25
|
+
|
26
|
+
def fetch_secret(scrt_id, label = nil)
|
27
|
+
scrt = ::Zanzibar::Zanzibar.new(@zanzibar_options)
|
28
|
+
|
29
|
+
puts @zanzibar_options
|
30
|
+
|
31
|
+
if label
|
32
|
+
scrt.download_secret_file(scrt_id: scrt_id,
|
33
|
+
type: label)
|
34
|
+
else
|
35
|
+
scrt.get_password(scrt_id)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def construct_options
|
40
|
+
@zanzibar_options[:wsdl] = construct_wsdl
|
41
|
+
@zanzibar_options[:globals] = { ssl_verify_mode: :none } if options['ignoressl']
|
42
|
+
@zanzibar_options[:domain] = options['domain']
|
43
|
+
@zanzibar_options[:username] = options['username'] unless options['username'].nil?
|
44
|
+
@zanzibar_options[:domain] = options['domain'] ? options['domain'] : 'local'
|
45
|
+
end
|
46
|
+
|
47
|
+
def construct_wsdl
|
48
|
+
if options['wsdl'].nil? && options['server']
|
49
|
+
DEFAULT_WSDL % options['server']
|
50
|
+
else
|
51
|
+
options['wsdl']
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def ensure_options
|
56
|
+
return if @zanzibar_options[:wsdl]
|
57
|
+
fail Error, NO_WSDL_ERROR
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'zanzibar/actions/base'
|
2
|
+
require 'zanzibar/error'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'erb'
|
5
|
+
require 'zanzibar/defaults'
|
6
|
+
|
7
|
+
module Zanzibar
|
8
|
+
module Actions
|
9
|
+
# Create a new Zanzifile
|
10
|
+
class Init < Base
|
11
|
+
def run
|
12
|
+
check_for_zanzifile
|
13
|
+
write_template
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def check_for_zanzifile
|
19
|
+
return unless File.exist?(ZANZIFILE_NAME) && !options['force']
|
20
|
+
fail Error, ALREADY_EXISTS_ERROR
|
21
|
+
end
|
22
|
+
|
23
|
+
def write_template
|
24
|
+
template = TemplateRenderer.new(options)
|
25
|
+
|
26
|
+
File.open(ZANZIFILE_NAME, 'w') do |f|
|
27
|
+
f.write template.render(File.read(source_root.join(TEMPLATE_NAME)))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Allows us to easily feed our options hash
|
32
|
+
# to an ERB
|
33
|
+
class TemplateRenderer < OpenStruct
|
34
|
+
def render(template)
|
35
|
+
ERB.new(template).result(binding)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/zanzibar/cli.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thor/actions'
|
3
|
+
require 'zanzibar/version'
|
4
|
+
require 'zanzibar/cli'
|
5
|
+
require 'zanzibar/ui'
|
6
|
+
require 'zanzibar/actions'
|
7
|
+
require 'zanzibar/error'
|
8
|
+
require 'zanzibar/defaults'
|
9
|
+
|
10
|
+
module Zanzibar
|
11
|
+
# The `zanzibar` binay/thor application main class
|
12
|
+
class Cli < Thor
|
13
|
+
include Thor::Actions
|
14
|
+
|
15
|
+
attr_accessor :ui
|
16
|
+
|
17
|
+
def initialize(*)
|
18
|
+
super
|
19
|
+
the_shell = (options['no-color'] ? Thor::Shell::Basic.new : shell)
|
20
|
+
@ui = Shell.new(the_shell)
|
21
|
+
@ui.be_quiet! if options['quiet']
|
22
|
+
@ui.debug! if options['verbose']
|
23
|
+
|
24
|
+
debug_header
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'version', 'Display your Zanzibar verion'
|
28
|
+
def version
|
29
|
+
say "#{APPLICATION_NAME} Version: #{VERSION}"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'init', "Create an empty #{ZANZIFILE_NAME} in the current directory."
|
33
|
+
option 'verbose', type: :boolean, default: false, aliases: :v
|
34
|
+
option 'wsdl', type: :string, aliases: :w,
|
35
|
+
default: DEFAULT_WSDL % DEFAULT_SERVER,
|
36
|
+
desc: 'The URI of the WSDL file for your Secret Server instance'
|
37
|
+
option 'domain', type: :string, default: 'local', aliases: :d,
|
38
|
+
desc: 'The logon domain for your Secret Server account'
|
39
|
+
option 'force', type: :boolean, default: false, aliases: :f,
|
40
|
+
desc: 'Recreate the Zanzifile if one already exists.'
|
41
|
+
option 'secretdir', type: :string, default: 'secrets/', aliases: :s,
|
42
|
+
desc: 'The directory to which secrets should be downloaded.'
|
43
|
+
option 'ignoressl', type: :boolean, default: 'false', aliases: :k,
|
44
|
+
desc: 'Don\'t check the SSL certificate of Secret Server'
|
45
|
+
def init
|
46
|
+
run_action { init! }
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'bundle', "Fetch secrets declared in your #{ZANZIFILE_NAME}"
|
50
|
+
option 'verbose', type: :boolean, default: false, aliases: :v
|
51
|
+
def bundle
|
52
|
+
run_action { bundle! }
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'plunder', "Alias to `#{APPLICATION_NAME} bundle`", :hide => true
|
56
|
+
alias_method :plunder, :bundle
|
57
|
+
|
58
|
+
desc 'install', "Alias to `#{APPLICATION_NAME} bundle`"
|
59
|
+
alias_method :install, :bundle
|
60
|
+
|
61
|
+
desc 'update', "Redownload all secrets in your #{ZANZIFILE_NAME}"
|
62
|
+
option 'verbose', type: :boolean, default: false, aliases: :v
|
63
|
+
def update
|
64
|
+
run_action { update! }
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'get SECRETID', 'Fetch a single SECRETID from Secret Server'
|
68
|
+
option 'domain', type: :string, aliases: :d,
|
69
|
+
desc: 'The logon domain to use when logging in.'
|
70
|
+
option 'server', type: :string, aliases: :s,
|
71
|
+
desc: 'The Secret Server hostname or IP'
|
72
|
+
option 'wsdl', type: :string, aliases: :w,
|
73
|
+
desc: 'Full path to the Secret Server WSDL'
|
74
|
+
option 'ignoressl', type: :boolean, aliases: :k,
|
75
|
+
desc: 'Don\'t verify Secret Server\'s SSL certificate'
|
76
|
+
option 'filelabel', type: :string, aliases: :f,
|
77
|
+
desc: 'Specify a file (by label) to download'
|
78
|
+
option 'username', type: :string, aliases: :u
|
79
|
+
option 'password', type: :string, aliases: :p
|
80
|
+
def get(scrt_id)
|
81
|
+
run_action { get! scrt_id }
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def debug_header
|
87
|
+
@ui.debug { "Running #{APPLICATION_NAME} in debug mode..." }
|
88
|
+
@ui.debug { "Ruby Version: #{RUBY_VERSION}" }
|
89
|
+
@ui.debug { "Ruby Platform: #{RUBY_PLATFORM}" }
|
90
|
+
@ui.debug { "#{APPLICATION_NAME} Version: #{VERSION}" }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Run the specified action and rescue errors we
|
94
|
+
# explicitly send back to format them
|
95
|
+
def run_action(&_block)
|
96
|
+
yield
|
97
|
+
rescue ::Zanzibar::Error => e
|
98
|
+
@ui.error e
|
99
|
+
abort "Fatal error: #{e.message}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def init!
|
103
|
+
say "Initializing a new #{ZANZIFILE_NAME} in the current directory..."
|
104
|
+
Actions::Init.new(@ui, options).run
|
105
|
+
say "Your #{ZANZIFILE_NAME} has been created!"
|
106
|
+
say 'You should check the settings and add your secrets.'
|
107
|
+
say 'Then run `zanzibar bundle` to fetch them.'
|
108
|
+
end
|
109
|
+
|
110
|
+
def bundle!
|
111
|
+
say "Checking for secrets declared in your #{ZANZIFILE_NAME}..."
|
112
|
+
Actions::Bundle.new(@ui, options).run
|
113
|
+
say 'Finished downloading secrets!'
|
114
|
+
end
|
115
|
+
|
116
|
+
def update!
|
117
|
+
say "Redownloading all secrets declared in your #{ZANZIFILE_NAME}..."
|
118
|
+
Actions::Bundle.new(@ui, options, update: true).run
|
119
|
+
say 'Finished downloading secrets!'
|
120
|
+
end
|
121
|
+
|
122
|
+
def get!(scrt_id)
|
123
|
+
say Actions::Get.new(@ui, options, scrt_id).run
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Definitions for various strings used throughout the gem
|
2
|
+
module Zanzibar
|
3
|
+
APPLICATION_NAME = Pathname.new($PROGRAM_NAME).basename
|
4
|
+
ZANZIFILE_NAME = 'Zanzifile'
|
5
|
+
RESOLVED_NAME = 'Zanzifile.resolved'
|
6
|
+
TEMPLATE_NAME = 'templates/Zanzifile.erb'
|
7
|
+
DEFAULT_SERVER = 'secret.example.com'
|
8
|
+
DEFAULT_WSDL = 'https://%s/webservices/sswebservice.asmx?wsdl'
|
9
|
+
|
10
|
+
ALREADY_EXISTS_ERROR = "#{ZANZIFILE_NAME} already exists! Aborting..."
|
11
|
+
NO_WSDL_ERROR = 'Could not construct WSDL URL. Please provide either --server or --wsdl'
|
12
|
+
NO_ZANZIFILE_ERROR = "You don't have a #{ZANZIFILE_NAME}! Run `#{APPLICATION_NAME} init` first!"
|
13
|
+
INVALID_ZANZIFILE_ERROR = "Unable to load your #{ZANZIFILE_NAME}. Please ensure it is valid YAML."
|
14
|
+
end
|