enfcli 3.3.2.pre.alpha
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/.circleci/Dockerfile +11 -0
- data/.circleci/build.sh +74 -0
- data/.circleci/config.yml +108 -0
- data/.circleci/setup-rubygems.sh +3 -0
- data/.gitignore +51 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +81 -0
- data/LICENSE +201 -0
- data/Makefile +28 -0
- data/README.md +67 -0
- data/Rakefile +14 -0
- data/bin/enfcli +5 -0
- data/enfcli.gemspec +46 -0
- data/lib/enfapi.rb +398 -0
- data/lib/enfcli/commands/user.rb +185 -0
- data/lib/enfcli/commands/xcr.rb +480 -0
- data/lib/enfcli/commands/xfw.rb +151 -0
- data/lib/enfcli/commands/xiam.rb +562 -0
- data/lib/enfcli/version.rb +18 -0
- data/lib/enfcli.rb +390 -0
- data/lib/enfthor.rb +118 -0
- metadata +218 -0
data/lib/enfcli.rb
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2018 Xaptum,Inc
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
require 'openssl'
|
|
17
|
+
require 'enfapi'
|
|
18
|
+
require 'enfthor'
|
|
19
|
+
require 'readline'
|
|
20
|
+
require 'singleton'
|
|
21
|
+
require 'ipaddr'
|
|
22
|
+
|
|
23
|
+
require 'rubygems/commands/update_command'
|
|
24
|
+
require 'rubygems/commands/search_command'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
require 'enfcli/version'
|
|
28
|
+
require 'enfcli/commands/xcr'
|
|
29
|
+
require 'enfcli/commands/xiam'
|
|
30
|
+
require 'enfcli/commands/xfw'
|
|
31
|
+
require 'enfcli/commands/user'
|
|
32
|
+
|
|
33
|
+
module EnfCli
|
|
34
|
+
FIREWALL_CMD = "firewall"
|
|
35
|
+
IAM_CMD = "iam"
|
|
36
|
+
NETWORK_CMD = "network"
|
|
37
|
+
USER_CMD = "user"
|
|
38
|
+
|
|
39
|
+
class IPV6
|
|
40
|
+
def initialize(ipv6)
|
|
41
|
+
begin
|
|
42
|
+
# create IPAddr object
|
|
43
|
+
ip = IPAddr.new ipv6
|
|
44
|
+
|
|
45
|
+
# make sure it is an ipv6 address
|
|
46
|
+
raise EnfCli::ERROR, "#{ipv6} is not a valid Ipv6 address." unless ip.ipv6?
|
|
47
|
+
|
|
48
|
+
@ip = ip
|
|
49
|
+
rescue IPAddr::InvalidAddressError
|
|
50
|
+
raise EnfCli::ERROR, "#{ipv6} is not a valid Ipv6 address."
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def to_s
|
|
55
|
+
@ip.to_s
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def hton
|
|
59
|
+
@ip.hton
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.ntoh ipv6_bytes
|
|
63
|
+
ip = IPAddr::new_ntoh( ipv6_bytes )
|
|
64
|
+
EnfCli::IPV6.new ip.to_s
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
attr_accessor :ip
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class IPV6Cidr
|
|
73
|
+
def initialize(ipv6cidr)
|
|
74
|
+
# split on /
|
|
75
|
+
tokens = ipv6cidr.split("/")
|
|
76
|
+
|
|
77
|
+
# raise exception if not cidr format
|
|
78
|
+
raise EnfCli::ERROR, "#{ipv6cidr} is not a valid CIDR notation." unless tokens.length == 2
|
|
79
|
+
|
|
80
|
+
# store in prefix/len
|
|
81
|
+
@prefix = EnfCli::IPV6.new tokens[0]
|
|
82
|
+
@len = tokens[1].to_i
|
|
83
|
+
|
|
84
|
+
# raise if len is not 0
|
|
85
|
+
raise EnfCli::ERROR, "#{ipv6cidr} is not a valid CIDR notation." unless len > 2
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def prefix_bytes
|
|
90
|
+
@prefix.hton
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def prefix_len
|
|
94
|
+
@len
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def to_s
|
|
98
|
+
"#{@prefix.to_s}/#{@len}"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
attr_accessor :prefix, :len
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def self.ask_password(prompt = nil)
|
|
106
|
+
begin
|
|
107
|
+
prompt = 'Enter Password:' unless prompt
|
|
108
|
+
print prompt
|
|
109
|
+
# We hide the entered characters before to ask for the password
|
|
110
|
+
system 'stty -echo'
|
|
111
|
+
password = $stdin.gets.chomp
|
|
112
|
+
system 'stty echo'
|
|
113
|
+
puts ""
|
|
114
|
+
return password
|
|
115
|
+
|
|
116
|
+
rescue NoMethodError, Interrupt
|
|
117
|
+
# When the process is exited, we display the characters again
|
|
118
|
+
# And we exit
|
|
119
|
+
system 'stty echo'
|
|
120
|
+
exit
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def self.generate_ec_cert(key, ipv6)
|
|
125
|
+
# monkey patch
|
|
126
|
+
OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
|
|
127
|
+
|
|
128
|
+
# Generate cert
|
|
129
|
+
cert = OpenSSL::X509::Certificate.new
|
|
130
|
+
cert.subject = cert.issuer = OpenSSL::X509::Name.new([['CN', "#{ipv6}"]])
|
|
131
|
+
cert.not_before = Time.now
|
|
132
|
+
cert.not_after = Time.now + 365 * 24 * 60 * 60
|
|
133
|
+
cert.public_key = key
|
|
134
|
+
cert.serial = 0x0
|
|
135
|
+
cert.version = 2
|
|
136
|
+
|
|
137
|
+
cert.sign key, OpenSSL::Digest::SHA1.new
|
|
138
|
+
cert
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def self.expand_path(file)
|
|
142
|
+
new_file = File.expand_path(EnfCli::expand_env(file))
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def self.expand_env(str)
|
|
146
|
+
str.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) { ENV[$1] }
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def self.to_canonical_ipv6(ipv6)
|
|
150
|
+
ip = EnfCli::IPV6.new ipv6
|
|
151
|
+
ip.to_s
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
##
|
|
155
|
+
# EnfCli error
|
|
156
|
+
#
|
|
157
|
+
class ERROR < StandardError
|
|
158
|
+
def initialize(msg = "Cli Error")
|
|
159
|
+
super
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
##
|
|
164
|
+
# EnfCli Context
|
|
165
|
+
#
|
|
166
|
+
class CTX
|
|
167
|
+
include Singleton
|
|
168
|
+
|
|
169
|
+
attr_accessor :session
|
|
170
|
+
|
|
171
|
+
def initialize
|
|
172
|
+
@prompt = "enfcli"
|
|
173
|
+
@host = ''
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def xaptum_admin?
|
|
177
|
+
self.user_role == "XAPTUM_ADMIN"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def user_role
|
|
181
|
+
@session[:type]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def host
|
|
185
|
+
"#{@host}"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def host=(value)
|
|
189
|
+
@host = value
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def prompt
|
|
193
|
+
"\001\033[1;32m\002#{@prompt}>\001\033[0m\002 "
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def prompt=(value)
|
|
197
|
+
if value
|
|
198
|
+
@prompt = "enfcli-#{value}"
|
|
199
|
+
else
|
|
200
|
+
@prompt= "enfcli"
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
##
|
|
208
|
+
# CLI for launching shell
|
|
209
|
+
#
|
|
210
|
+
class CLI < EnfThor
|
|
211
|
+
no_commands {
|
|
212
|
+
def execute_gem_cmd cmd
|
|
213
|
+
begin
|
|
214
|
+
cmd.execute
|
|
215
|
+
rescue Gem::SystemExitException => e
|
|
216
|
+
say "Unable to execute commnad. Please try again!", :red
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
desc "connect", "Connect to ENF Controller"
|
|
222
|
+
method_option :host, :type => :string, :required => true
|
|
223
|
+
method_option :user, :type => :string, :required => true
|
|
224
|
+
method_option :password, :type => :string
|
|
225
|
+
def connect(*names)
|
|
226
|
+
host = options[:host]
|
|
227
|
+
user = options[:user]
|
|
228
|
+
|
|
229
|
+
try_with_rescue do
|
|
230
|
+
# Make sure to use https as default
|
|
231
|
+
host = "https://#{host}" unless host =~ /^(http|https):\/\//
|
|
232
|
+
|
|
233
|
+
# Ask for password
|
|
234
|
+
say "Connecting to '#{host}'.....", :bold
|
|
235
|
+
password = EnfCli::ask_password()
|
|
236
|
+
|
|
237
|
+
# Authenticate
|
|
238
|
+
resp = EnfApi::API.instance.authenticate(host, user, password)
|
|
239
|
+
|
|
240
|
+
# set session
|
|
241
|
+
EnfCli::CTX.instance.session = resp[:data][0]
|
|
242
|
+
|
|
243
|
+
# launch shell/exec cmd
|
|
244
|
+
if names.empty?
|
|
245
|
+
EnfCli::Shell::Console::start host, user
|
|
246
|
+
else
|
|
247
|
+
EnfCli::Shell::CLI.start names
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
map %w[--version -v] => :__print_version
|
|
253
|
+
desc "--version, -v", "print the version"
|
|
254
|
+
def __print_version
|
|
255
|
+
puts EnfCli::VERSION
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
desc "update", "", :hide => true
|
|
259
|
+
def update
|
|
260
|
+
cmd = Gem::Commands::UpdateCommand.new
|
|
261
|
+
cmd.handle_options ['enfcli']
|
|
262
|
+
execute_gem_cmd cmd
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
desc "search", "", :hide => true
|
|
266
|
+
def search
|
|
267
|
+
cmd = Gem::Commands::SearchCommand.new
|
|
268
|
+
cmd.handle_options ["enfcli"]
|
|
269
|
+
execute_gem_cmd cmd
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
default_task :connect
|
|
273
|
+
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
##
|
|
277
|
+
# Shell Module
|
|
278
|
+
#
|
|
279
|
+
module Shell
|
|
280
|
+
|
|
281
|
+
class Console
|
|
282
|
+
class << self
|
|
283
|
+
def execute(input)
|
|
284
|
+
argv = input.split(" ")
|
|
285
|
+
EnfCli::Shell::CLI.start( argv )
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def start(host, user)
|
|
289
|
+
# Set prompt
|
|
290
|
+
EnfCli::CTX.instance.prompt = user
|
|
291
|
+
|
|
292
|
+
# Set host
|
|
293
|
+
EnfCli::CTX.instance.host = host
|
|
294
|
+
|
|
295
|
+
# Read each line
|
|
296
|
+
comp = proc { |s| Readline::HISTORY.grep(/^#{Regexp.escape(s)}/) }
|
|
297
|
+
Readline.completion_append_character = " "
|
|
298
|
+
Readline.completion_proc = comp
|
|
299
|
+
|
|
300
|
+
stty_save = `stty -g`.chomp
|
|
301
|
+
trap('INT') { system('stty', stty_save); exit }
|
|
302
|
+
|
|
303
|
+
while input = Readline.readline(EnfCli::CTX.instance.prompt, true)
|
|
304
|
+
break if input == "exit" or input == "\\q" or input == "quit"
|
|
305
|
+
|
|
306
|
+
# Remove blank lines from history
|
|
307
|
+
Readline::HISTORY.pop if input == ""
|
|
308
|
+
|
|
309
|
+
execute(input) unless input == ""
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# Shell CLI class
|
|
316
|
+
class CLI < EnfThor
|
|
317
|
+
|
|
318
|
+
desc "ls [<dir>]", "List files in a directory", :hide => true
|
|
319
|
+
method_option :dir, :type => :string, :required => false
|
|
320
|
+
def ls(dir = nil)
|
|
321
|
+
try_with_rescue do
|
|
322
|
+
dir = "." unless dir
|
|
323
|
+
dir = EnfCli::expand_path( dir )
|
|
324
|
+
|
|
325
|
+
Dir.entries( dir ).each{ |f|
|
|
326
|
+
puts f unless f.start_with?('.')
|
|
327
|
+
}
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
desc "cat <file>", "Display contents of a file", :hide => true
|
|
332
|
+
def cat(file)
|
|
333
|
+
try_with_rescue do
|
|
334
|
+
# expand path
|
|
335
|
+
file = EnfCli::expand_path(file)
|
|
336
|
+
|
|
337
|
+
## return if keyfile not found
|
|
338
|
+
raise EnfCli::ERROR, "#{file} not found!" unless File.exists?(file)
|
|
339
|
+
|
|
340
|
+
say File.readlines(file).join
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
desc "pwd", "Current Working Directory", :hide => true
|
|
345
|
+
def pwd
|
|
346
|
+
try_with_rescue do
|
|
347
|
+
say Dir.pwd
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
desc "cd [<dir>]", "Change working directory", :hide => true
|
|
352
|
+
def cd(dir = "~")
|
|
353
|
+
try_with_rescue do
|
|
354
|
+
dir = EnfCli::expand_path( dir )
|
|
355
|
+
raise EnfCli::ERROR, "No such directory #{dir}" unless Dir.exist?(dir)
|
|
356
|
+
Dir.chdir(dir)
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
desc "host", "Display ENF Controller host", :hide => true
|
|
361
|
+
def host
|
|
362
|
+
try_with_rescue do
|
|
363
|
+
say EnfCli::CTX.instance.host, :bold
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
desc "clear", "Clear Terminal Screen", :hide => true
|
|
368
|
+
def clear
|
|
369
|
+
try_with_rescue do
|
|
370
|
+
clear_code = %x{clear}
|
|
371
|
+
print clear_code or system("cls")
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
desc "#{EnfCli::NETWORK_CMD} COMMANDS", "#{EnfCli::NETWORK_CMD} commands"
|
|
376
|
+
subcommand EnfCli::NETWORK_CMD, EnfCli::Cmd::Xcr
|
|
377
|
+
|
|
378
|
+
desc "#{EnfCli::IAM_CMD} COMMANDS", "#{EnfCli::IAM_CMD} commands"
|
|
379
|
+
subcommand EnfCli::IAM_CMD, EnfCli::Cmd::Xiam
|
|
380
|
+
|
|
381
|
+
desc "#{EnfCli::FIREWALL_CMD} COMMANDS", "#{EnfCli::FIREWALL_CMD} commands"
|
|
382
|
+
subcommand EnfCli::FIREWALL_CMD, EnfCli::Cmd::Xfw
|
|
383
|
+
|
|
384
|
+
desc "#{EnfCli::USER_CMD} COMMANDS", "#{EnfCli::USER_CMD} commands"
|
|
385
|
+
subcommand EnfCli::USER_CMD, EnfCli::Cmd::User
|
|
386
|
+
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
end
|
data/lib/enfthor.rb
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2018 Xaptum,Inc
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
require 'thor'
|
|
17
|
+
require 'terminal-table'
|
|
18
|
+
|
|
19
|
+
module EnfCli
|
|
20
|
+
class EnfThor < Thor
|
|
21
|
+
# check for unknow of misspelt options
|
|
22
|
+
check_unknown_options!
|
|
23
|
+
|
|
24
|
+
# helper functions
|
|
25
|
+
no_commands {
|
|
26
|
+
|
|
27
|
+
def format_date(date)
|
|
28
|
+
DateTime.strptime("#{date}",'%s') if date
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def render_table(headings, rows, file = nil)
|
|
32
|
+
table = Terminal::Table.new
|
|
33
|
+
table.headings = headings
|
|
34
|
+
table.rows = rows
|
|
35
|
+
if file
|
|
36
|
+
open(expand_path(file), 'w') { |f|
|
|
37
|
+
f.puts table
|
|
38
|
+
}
|
|
39
|
+
say "#{rows.length} rows written to file #{file}", :yellow
|
|
40
|
+
else
|
|
41
|
+
say table
|
|
42
|
+
say "#{rows.length} rows in set", :yellow
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def try_with_rescue_in_session
|
|
47
|
+
try_with_rescue do
|
|
48
|
+
# Verify domain context is set
|
|
49
|
+
session = EnfCli::CTX.instance.session
|
|
50
|
+
raise EnfCli::ERROR, "User Session not establised!" if !session
|
|
51
|
+
|
|
52
|
+
yield
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def try_with_rescue
|
|
57
|
+
begin
|
|
58
|
+
yield
|
|
59
|
+
rescue EnfApi::ERROR => e
|
|
60
|
+
say e, :red
|
|
61
|
+
|
|
62
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
63
|
+
say e, :red
|
|
64
|
+
say "Host may not support https. Try http instead", :bold
|
|
65
|
+
|
|
66
|
+
rescue => e
|
|
67
|
+
say e, :red
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# override help methods
|
|
75
|
+
class << self
|
|
76
|
+
def capture_stdout
|
|
77
|
+
$stdout = StringIO.new
|
|
78
|
+
yield
|
|
79
|
+
text = $stdout.string
|
|
80
|
+
$stdout = STDOUT
|
|
81
|
+
text
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def help(shell, subcommand = false)
|
|
85
|
+
list = printable_commands(true, subcommand)
|
|
86
|
+
Thor::Util.thor_classes_in(self).each do |klass|
|
|
87
|
+
list += klass.printable_commands(false)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Remove this line to disable alphabetical sorting
|
|
91
|
+
list.sort! { |a, b| a[0] <=> b[0] }
|
|
92
|
+
|
|
93
|
+
# Add this line to remove the help-command itself from the output
|
|
94
|
+
list.reject! {|l| l[0].split[1] == 'help' or l[0].split[2] == 'help'}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# Capture help message in a variable
|
|
98
|
+
help_text = capture_stdout {
|
|
99
|
+
shell.say "Commands:"
|
|
100
|
+
shell.print_table(list, :indent => 2, :truncate => true)
|
|
101
|
+
shell.say
|
|
102
|
+
class_options_help(shell)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
## HACK: format to display proper help message for help command run from shell
|
|
106
|
+
help_text = help_text.gsub(/enfcli /,"") unless self == EnfCli::CLI
|
|
107
|
+
|
|
108
|
+
# Print the actual help message
|
|
109
|
+
shell.say help_text
|
|
110
|
+
|
|
111
|
+
# Add this line if you want to print custom text at the end of your help output.
|
|
112
|
+
# (similar to how Rails does it)
|
|
113
|
+
shell.say 'All commands can be run with -h (or --help) for more information.'
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: enfcli
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 3.3.2.pre.alpha
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Venkatakumar Srinivasan
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-03-29 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: thor
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.20.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.20.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rest-client
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: terminal-table
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '10.0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '10.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: bump
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rspec
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rspec_junit_formatter
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: fuubar
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: vcr
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: webmock
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
167
|
+
description:
|
|
168
|
+
email:
|
|
169
|
+
- venkat@xaptum.com
|
|
170
|
+
executables:
|
|
171
|
+
- enfcli
|
|
172
|
+
extensions: []
|
|
173
|
+
extra_rdoc_files: []
|
|
174
|
+
files:
|
|
175
|
+
- ".circleci/Dockerfile"
|
|
176
|
+
- ".circleci/build.sh"
|
|
177
|
+
- ".circleci/config.yml"
|
|
178
|
+
- ".circleci/setup-rubygems.sh"
|
|
179
|
+
- ".gitignore"
|
|
180
|
+
- Gemfile
|
|
181
|
+
- Gemfile.lock
|
|
182
|
+
- LICENSE
|
|
183
|
+
- Makefile
|
|
184
|
+
- README.md
|
|
185
|
+
- Rakefile
|
|
186
|
+
- bin/enfcli
|
|
187
|
+
- enfcli.gemspec
|
|
188
|
+
- lib/enfapi.rb
|
|
189
|
+
- lib/enfcli.rb
|
|
190
|
+
- lib/enfcli/commands/user.rb
|
|
191
|
+
- lib/enfcli/commands/xcr.rb
|
|
192
|
+
- lib/enfcli/commands/xfw.rb
|
|
193
|
+
- lib/enfcli/commands/xiam.rb
|
|
194
|
+
- lib/enfcli/version.rb
|
|
195
|
+
- lib/enfthor.rb
|
|
196
|
+
homepage: https://www.xaptum.com
|
|
197
|
+
licenses: []
|
|
198
|
+
metadata: {}
|
|
199
|
+
post_install_message:
|
|
200
|
+
rdoc_options: []
|
|
201
|
+
require_paths:
|
|
202
|
+
- lib
|
|
203
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
|
+
requirements:
|
|
205
|
+
- - ">="
|
|
206
|
+
- !ruby/object:Gem::Version
|
|
207
|
+
version: '0'
|
|
208
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
|
+
requirements:
|
|
210
|
+
- - ">"
|
|
211
|
+
- !ruby/object:Gem::Version
|
|
212
|
+
version: 1.3.1
|
|
213
|
+
requirements: []
|
|
214
|
+
rubygems_version: 3.0.1
|
|
215
|
+
signing_key:
|
|
216
|
+
specification_version: 4
|
|
217
|
+
summary: Xaptum ENF CLI.
|
|
218
|
+
test_files: []
|