collins_shell 0.2.14
Sign up to get free protection for your applications and to get access to all the features.
- data/.pryrc +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +59 -0
- data/README.md +335 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/bin/collins-shell +36 -0
- data/collins_shell.gemspec +95 -0
- data/lib/collins_shell.rb +3 -0
- data/lib/collins_shell/asset.rb +198 -0
- data/lib/collins_shell/cli.rb +185 -0
- data/lib/collins_shell/console.rb +129 -0
- data/lib/collins_shell/console/asset.rb +127 -0
- data/lib/collins_shell/console/cache.rb +17 -0
- data/lib/collins_shell/console/command_helpers.rb +131 -0
- data/lib/collins_shell/console/commands.rb +28 -0
- data/lib/collins_shell/console/commands/cat.rb +123 -0
- data/lib/collins_shell/console/commands/cd.rb +61 -0
- data/lib/collins_shell/console/commands/io.rb +26 -0
- data/lib/collins_shell/console/commands/iterators.rb +190 -0
- data/lib/collins_shell/console/commands/tail.rb +178 -0
- data/lib/collins_shell/console/commands/versions.rb +42 -0
- data/lib/collins_shell/console/filesystem.rb +121 -0
- data/lib/collins_shell/console/options_helpers.rb +8 -0
- data/lib/collins_shell/errors.rb +7 -0
- data/lib/collins_shell/ip_address.rb +144 -0
- data/lib/collins_shell/ipmi.rb +67 -0
- data/lib/collins_shell/monkeypatch.rb +60 -0
- data/lib/collins_shell/provision.rb +152 -0
- data/lib/collins_shell/state.rb +98 -0
- data/lib/collins_shell/tag.rb +41 -0
- data/lib/collins_shell/thor.rb +209 -0
- data/lib/collins_shell/util.rb +120 -0
- data/lib/collins_shell/util/asset_printer.rb +265 -0
- data/lib/collins_shell/util/asset_stache.rb +32 -0
- data/lib/collins_shell/util/log_printer.rb +187 -0
- data/lib/collins_shell/util/printer_util.rb +28 -0
- metadata +200 -0
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'collins_shell/thor'
|
2
|
+
require 'collins_shell/util'
|
3
|
+
require 'thor'
|
4
|
+
require 'thor/group'
|
5
|
+
require 'terminal-table'
|
6
|
+
|
7
|
+
module CollinsShell
|
8
|
+
|
9
|
+
class Provision < Thor
|
10
|
+
include ThorHelper
|
11
|
+
include CollinsShell::Util
|
12
|
+
|
13
|
+
desc 'list', 'list available provisioning profiles'
|
14
|
+
use_collins_options
|
15
|
+
def list
|
16
|
+
table = Terminal::Table.new
|
17
|
+
table.title = set_color("Provisioning Profiles", :bold, :magenta)
|
18
|
+
table << [
|
19
|
+
"Profile", "Label", "Prefix", "Pool", split("Primary Role"), split("Secondary Role"),
|
20
|
+
split("Suffix Allowed?"), split("Requires Primary Role?"),
|
21
|
+
split("Requires Secondary Role?"), split("Requires Pool?")
|
22
|
+
]
|
23
|
+
table << :separator
|
24
|
+
data = call_collins get_collins_client, '/api/provision/profiles' do |client|
|
25
|
+
profs = client.provisioning_profiles
|
26
|
+
last = profs.size - 1
|
27
|
+
profs.each_with_index do |profile, idx|
|
28
|
+
table << [
|
29
|
+
profile.profile, split(profile.label), profile.prefix, optional_string(profile.pool),
|
30
|
+
optional_string(profile.primary_role), optional_string(profile.secondary_role),
|
31
|
+
centered(profile.suffix_allowed?), centered(profile.requires_primary_role?),
|
32
|
+
centered(profile.requires_secondary_role?), centered(profile.requires_pool?)
|
33
|
+
]
|
34
|
+
if idx != last && too_wide? then
|
35
|
+
table << :separator
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
puts table
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'host TAG PROFILE CONTACT', 'provision host with asset tag TAG as PROFILE, and then contact CONTACT'
|
43
|
+
long_desc <<-D
|
44
|
+
Provision the host specified by the TAG argument as a PROFILE.
|
45
|
+
|
46
|
+
PROFILE must be one of the profiles found by doing a `collins-shell provision list`
|
47
|
+
|
48
|
+
CONTACT should be your hipchat username, or the username part of your email address.
|
49
|
+
|
50
|
+
This task may take up to 90 seconds to return.
|
51
|
+
D
|
52
|
+
use_collins_options
|
53
|
+
method_option :activate, :type => :boolean, :desc => 'Activate a server', :hide => true
|
54
|
+
method_option :confirm, :type => :boolean, :default => :true, :desc => 'Require confirmation. Defaults to true'
|
55
|
+
method_option :exec, :type => :string, :desc => 'Execute a command using the data from this asset. Use {{hostname}}, {{ipmi.password}}, etc for substitution'
|
56
|
+
method_option :pool, :type => :string, :desc => 'Pool for host'
|
57
|
+
method_option :primary_role, :type => :string, :desc => 'Primary role for host'
|
58
|
+
method_option :secondary_role, :type => :string, :desc => 'Secondary role for host'
|
59
|
+
method_option :suffix, :type => :string, :desc => 'Suffix to use for hostname'
|
60
|
+
method_option :verify, :type => :boolean, :default => :true, :desc => 'Verify arguments locally first'
|
61
|
+
def host tag, profile, contact
|
62
|
+
verify_profile(profile) if options.verify
|
63
|
+
config = get_collins_config
|
64
|
+
if config[:timeout] < 180 then
|
65
|
+
cclient = get_collins_client :timeout => 180
|
66
|
+
else
|
67
|
+
cclient = get_collins_client
|
68
|
+
end
|
69
|
+
asset = asset_get tag, options
|
70
|
+
if options.confirm then
|
71
|
+
printer = CollinsShell::AssetPrinter.new asset, self, :detailed => false
|
72
|
+
puts printer
|
73
|
+
require_yes "You are about to provision asset #{tag} as a #{profile}. ARE YOU SURE?", :red
|
74
|
+
end
|
75
|
+
progress_printer = Thread.new {
|
76
|
+
loop {
|
77
|
+
print "."
|
78
|
+
sleep(1)
|
79
|
+
}
|
80
|
+
}
|
81
|
+
status = call_collins cclient, "provision host" do |client|
|
82
|
+
say_status("starting", "Provisioning has started", :white)
|
83
|
+
client.provision tag, profile, contact, :activate => options.activate,
|
84
|
+
:pool => options.pool,
|
85
|
+
:primary_role => options.primary_role,
|
86
|
+
:secondary_role => options.secondary_role,
|
87
|
+
:suffix => options.suffix
|
88
|
+
end
|
89
|
+
progress_printer.terminate
|
90
|
+
puts()
|
91
|
+
if status then
|
92
|
+
say_success("Successfully provisioned asset")
|
93
|
+
asset = asset_get tag, options
|
94
|
+
printer = CollinsShell::AssetPrinter.new asset, self, :detailed => false
|
95
|
+
puts printer
|
96
|
+
asset_exec asset, options.exec, options.confirm
|
97
|
+
else
|
98
|
+
say_error("Failed to provision asset")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
no_tasks do
|
103
|
+
def too_wide?
|
104
|
+
terminal_width < 150
|
105
|
+
end
|
106
|
+
|
107
|
+
def split value
|
108
|
+
if too_wide? then
|
109
|
+
value.split(' ').join("\n")
|
110
|
+
else
|
111
|
+
value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def verify_value pname, name, user_specified, profile_exists, profile_requires, profile_provides
|
116
|
+
if user_specified then
|
117
|
+
require_that(!profile_exists, "#{name} is not user configurable for '#{pname}'")
|
118
|
+
else
|
119
|
+
require_that(!profile_requires || profile_provides, "#{name} is required for '#{pname}'")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def verify_profile pname
|
124
|
+
profiles = call_collins get_collins_client, '/api/provision/profiles' do |client|
|
125
|
+
client.provisioning_profiles
|
126
|
+
end
|
127
|
+
profile = profiles.select{|p| p.profile.downcase == pname.to_s.downcase}.first
|
128
|
+
require_non_empty(profile, "No such profile '#{pname}', try collins-shell provision list")
|
129
|
+
if options.suffix? then
|
130
|
+
require_that(profile.suffix_allowed?, "Suffix not allowed for '#{pname}'")
|
131
|
+
end
|
132
|
+
verify_value pname, "Pool", options.pool?, profile.pool?, profile.requires_pool?, profile.pool
|
133
|
+
verify_value pname, "Secondary role", options.secondary_role?, profile.secondary_role?, profile.requires_secondary_role?, profile.secondary_role
|
134
|
+
verify_value pname, "Primary role", options.primary_role?, profile.primary_role?, profile.requires_primary_role?, profile.primary_role
|
135
|
+
end
|
136
|
+
|
137
|
+
def centered value
|
138
|
+
{:alignment => :center, :value => value}
|
139
|
+
end
|
140
|
+
|
141
|
+
def optional_string value, default = 'Configurable'
|
142
|
+
if value.nil? || value.empty? then
|
143
|
+
default
|
144
|
+
else
|
145
|
+
value
|
146
|
+
end
|
147
|
+
end # optional_string
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'collins_shell/thor'
|
2
|
+
require 'collins_shell/util'
|
3
|
+
require 'thor'
|
4
|
+
require 'thor/group'
|
5
|
+
|
6
|
+
module CollinsShell
|
7
|
+
|
8
|
+
class State < Thor
|
9
|
+
include ThorHelper
|
10
|
+
include CollinsShell::Util
|
11
|
+
namespace :state
|
12
|
+
|
13
|
+
def self.banner task, namespace = true, subcommand = false
|
14
|
+
"#{basename} #{task.formatted_usage(self, true, subcommand).gsub(':',' ')}"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'create', 'Create a new state'
|
18
|
+
use_collins_options
|
19
|
+
method_option :name, :type => :string, :required => true, :desc => 'Name of state. Must be all caps and unique. Can contain numbers, letters and underscores.'
|
20
|
+
method_option :label, :type => :string, :required => true, :desc => 'A friendly (short) description of the state to use in visual labels. Usually just a camel case version of the name, possibly with spaces.'
|
21
|
+
method_option :description, :type => :string, :required => true, :desc => 'A longer description of the state'
|
22
|
+
method_option :status, :type => :string, :required => false, :desc => 'Optional status to bind the state to'
|
23
|
+
def create
|
24
|
+
name = options.name.upcase
|
25
|
+
label = options.label
|
26
|
+
desc = options.description
|
27
|
+
status = options.status
|
28
|
+
call_collins get_collins_client, "state_create!" do |client|
|
29
|
+
if client.state_create!(name, label, desc, status) then
|
30
|
+
say_success "Successfully created state '#{name}'"
|
31
|
+
else
|
32
|
+
say_error "Failed creating state '#{name}'"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'delete STATE', 'Delete a state'
|
38
|
+
use_collins_options
|
39
|
+
def delete state
|
40
|
+
call_collins get_collins_client, "state_delete!" do |client|
|
41
|
+
if client.state_delete!(state) then
|
42
|
+
say_success "Successfully deleted state '#{state}'"
|
43
|
+
else
|
44
|
+
say_error "Failed deleting state '#{state}'"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'get STATE', 'Get a state by name'
|
50
|
+
use_collins_options
|
51
|
+
def get state
|
52
|
+
call_collins get_collins_client, "state_get" do |client|
|
53
|
+
header = [["Name", "Label", "Status", "Description"]]
|
54
|
+
state = client.state_get(state)
|
55
|
+
table = header + [[state.name, state.label, (state.status.name || ""), state.description]]
|
56
|
+
print_table table
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
desc 'list', 'list states that are available'
|
61
|
+
use_collins_options
|
62
|
+
def list
|
63
|
+
call_collins get_collins_client, "state_get_all" do |client|
|
64
|
+
header = [["Name", "Label", "Status", "Description"]]
|
65
|
+
states = header + client.state_get_all.map do |state|
|
66
|
+
[state.name, state.label, (state.status.name || ""), state.description]
|
67
|
+
end
|
68
|
+
print_table states
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'update STATE', 'Update the name, label, description or status binding of a state'
|
73
|
+
use_collins_options
|
74
|
+
method_option :name, :type => :string, :required => false, :desc => 'New name of state. Must be all caps and unique. Can contains numbers, letters, and underscores.'
|
75
|
+
method_option :label, :type => :string, :required => false, :desc => 'A friendly (short) description of the state to use in visual labels. Usually just a camel case version of the name, possibly with spaces.'
|
76
|
+
method_option :description, :type => :string, :required => false, :desc => 'A longer description of the state'
|
77
|
+
method_option :status, :type => :string, :required => false, :desc => 'Optional status to bind the state to'
|
78
|
+
def update state
|
79
|
+
name = options.name.upcase if options.name?
|
80
|
+
label = options.label if options.label?
|
81
|
+
desc = options.description if options.description?
|
82
|
+
status = options.status if options.status?
|
83
|
+
call_collins get_collins_client, "state_update!" do |client|
|
84
|
+
opts = {
|
85
|
+
:name => name, :label => label, :status => status,
|
86
|
+
:description => desc
|
87
|
+
}
|
88
|
+
if client.state_update!(state, opts) then
|
89
|
+
say_success "Successfully updated state '#{state}'"
|
90
|
+
else
|
91
|
+
say_error "Failed creating state '#{state}'"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'collins_shell/thor'
|
2
|
+
require 'collins_shell/util'
|
3
|
+
require 'thor'
|
4
|
+
require 'thor/group'
|
5
|
+
|
6
|
+
module CollinsShell
|
7
|
+
|
8
|
+
class Tag < Thor
|
9
|
+
|
10
|
+
include ThorHelper
|
11
|
+
include CollinsShell::Util
|
12
|
+
namespace :tag
|
13
|
+
|
14
|
+
def self.banner task, namespace = true, subcommand = false
|
15
|
+
"#{basename} #{task.formatted_usage(self, true, subcommand).gsub(':',' ')}"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'list', 'list tags that are in use'
|
19
|
+
use_collins_options
|
20
|
+
def list
|
21
|
+
call_collins get_collins_client, "list" do |client|
|
22
|
+
header = [["Name", "Label", "Description"]]
|
23
|
+
tags = header + client.get_all_tags.map do |tag|
|
24
|
+
[tag.name, tag.label, tag.description]
|
25
|
+
end
|
26
|
+
print_table tags
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'values TAG', 'list all values for the specified tag'
|
31
|
+
use_collins_options
|
32
|
+
def values tag
|
33
|
+
call_collins get_collins_client, "values" do |client|
|
34
|
+
client.get_tag_values(tag).sort.each do |value|
|
35
|
+
puts(value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'collins_client'
|
2
|
+
require 'highline'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module CollinsShell
|
6
|
+
module ThorHelper
|
7
|
+
|
8
|
+
include Collins::Util
|
9
|
+
|
10
|
+
COLLINS_OPTIONS = {
|
11
|
+
:config => {:type => :string, :desc => 'YAML configuration file'},
|
12
|
+
:debug => {:type => :boolean, :default => false, :desc => 'Debug output'},
|
13
|
+
:host => {:type => :string, :desc => 'Collins host (e.g. http://host:port)'},
|
14
|
+
:password => {:type => :string, :desc => 'Collins password'},
|
15
|
+
:quiet => {:type => :boolean, :default => false, :desc => 'Be quiet when appropriate'},
|
16
|
+
:timeout => {:type => :numeric, :default => 30, :desc => 'Collins client timeout'},
|
17
|
+
:username => {:type => :string, :desc => 'Collins username'}
|
18
|
+
}
|
19
|
+
|
20
|
+
PAGE_OPTIONS = {
|
21
|
+
:page => {:type => :numeric, :default => 0, :desc => 'Page of results set.'},
|
22
|
+
:size => {:type => :numeric, :default => 20, :desc => 'Number of results to return.'},
|
23
|
+
:sort => {:type => :string, :default => 'DESC', :desc => 'Sort direction. ASC or DESC'}
|
24
|
+
}
|
25
|
+
|
26
|
+
def self.included(base)
|
27
|
+
base.extend(ThorHelper)
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
attr_accessor :password
|
32
|
+
end
|
33
|
+
|
34
|
+
def use_collins_options
|
35
|
+
COLLINS_OPTIONS.each do |name, options|
|
36
|
+
method_option name, options
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def use_page_options default_size = 20
|
40
|
+
PAGE_OPTIONS.each do |name, options|
|
41
|
+
options.update(:default => default_size) if name == :size
|
42
|
+
method_option name, options
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def use_tag_option required = false
|
46
|
+
method_option :tag, :type => :string, :required => required, :desc => 'Tag for asset'
|
47
|
+
end
|
48
|
+
def use_selector_option required = false
|
49
|
+
method_option :selector, :type => :hash, :required => required, :desc => 'Selector to query collins. Takes the form of --selector=key1:val1 key2:val2 etc'
|
50
|
+
method_option :remote, :type => :boolean, :default => false, :desc => 'Search all collins instances, including remote ones'
|
51
|
+
end
|
52
|
+
|
53
|
+
def selector_or_tag
|
54
|
+
if options.selector? then
|
55
|
+
options.selector
|
56
|
+
elsif options.tag? then
|
57
|
+
{:tag => options.tag}
|
58
|
+
else
|
59
|
+
say_error "Either tag or selector must be specified", :exit => true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def require_yes message, color = nil, should_exit = true
|
64
|
+
highline = HighLine.new
|
65
|
+
colored_message = set_color(message, color)
|
66
|
+
answer = ask(colored_message)
|
67
|
+
if answer.downcase.strip !~ /^yes$/ then
|
68
|
+
if should_exit then
|
69
|
+
exit(0)
|
70
|
+
else
|
71
|
+
false
|
72
|
+
end
|
73
|
+
else
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def batch_selector_operation options = {}, &block
|
79
|
+
confirmation_message = options[:confirmation_message]
|
80
|
+
success_message = options[:success_message]
|
81
|
+
error_message = options[:error_message]
|
82
|
+
operation = options[:operation]
|
83
|
+
require_non_empty(confirmation_message, "confirmation_message option not set")
|
84
|
+
require_non_empty(success_message, "success_message not set")
|
85
|
+
require_non_empty(error_message, "error_message not set")
|
86
|
+
require_non_empty(operation, "operation not set")
|
87
|
+
selector = get_selector selector_or_tag, [], nil, options[:remote]
|
88
|
+
call_collins get_collins_client, operation do |client|
|
89
|
+
assets = client.find selector
|
90
|
+
if assets.length > 1 then
|
91
|
+
require_yes confirmation_message.call(assets), :red
|
92
|
+
end
|
93
|
+
assets.each do |asset|
|
94
|
+
if block.call(client, asset) then
|
95
|
+
say_success success_message.call(asset)
|
96
|
+
else
|
97
|
+
say_error error_message.call(asset)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def say_error message, options = {}
|
104
|
+
if options[:exception] then
|
105
|
+
say_status("error", "#{message} - #{options[:exception]}", :red)
|
106
|
+
if options[:debug] && options[:debug] then
|
107
|
+
pp options[:exception].backtrace
|
108
|
+
end
|
109
|
+
else
|
110
|
+
say_status("error", message, :red)
|
111
|
+
end
|
112
|
+
if options[:exit].is_a?(TrueClass) then
|
113
|
+
exit(1)
|
114
|
+
elsif not options[:exit].nil? then
|
115
|
+
exit(options[:exit])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def say_success message
|
120
|
+
say_status("success", message, :green)
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_collins_client opts = {}
|
124
|
+
config = get_collins_config.merge(opts).merge(:strict => true)
|
125
|
+
config = ensure_password opts
|
126
|
+
require_valid_collins_config config
|
127
|
+
config[:logger] = get_logger :trace => options.debug, :progname => 'collins-shell'
|
128
|
+
Collins::Client.new config
|
129
|
+
end
|
130
|
+
|
131
|
+
def ensure_password opts = {}
|
132
|
+
me = CollinsShell::ThorHelper
|
133
|
+
if me.password.nil? then
|
134
|
+
me.password = get_password(get_collins_config.merge(opts).merge(:strict => true))
|
135
|
+
end
|
136
|
+
me.password
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_password config
|
140
|
+
if
|
141
|
+
config[:password] and not
|
142
|
+
config[:password].empty? and
|
143
|
+
config[:password] != "password" then
|
144
|
+
return config
|
145
|
+
end
|
146
|
+
highline = HighLine.new
|
147
|
+
password = highline.ask("Enter your password: ") { |q| q.echo = "x" }
|
148
|
+
config.update(:password => password)
|
149
|
+
end
|
150
|
+
|
151
|
+
# --username --password --host is highest priority
|
152
|
+
# --config= second highest
|
153
|
+
# ~/.collins.yaml is lowest
|
154
|
+
def get_collins_config
|
155
|
+
def try_config_merge filename, config
|
156
|
+
file_config = collins_config_from_file filename
|
157
|
+
if file_config[:collins] then
|
158
|
+
file_config = file_config[:collins]
|
159
|
+
end
|
160
|
+
config.update(:host => file_config[:host]) unless options.host?
|
161
|
+
config.update(:username => file_config[:username]) unless options.username?
|
162
|
+
config.update(:password => file_config[:password]) unless options.password?
|
163
|
+
if options.timeout == 30 and file_config[:timeout] then
|
164
|
+
config.update(:timeout => file_config[:timeout].to_i)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
config = Hash[
|
168
|
+
:host => options.host,
|
169
|
+
:username => options.username,
|
170
|
+
:password => options.password,
|
171
|
+
:timeout => options.timeout
|
172
|
+
]
|
173
|
+
if ENV['COLLINS'] then
|
174
|
+
try_config_merge ENV['COLLINS'], config
|
175
|
+
end
|
176
|
+
if options.config? then
|
177
|
+
try_config_merge options.config, config
|
178
|
+
end
|
179
|
+
if File.exists?(File.expand_path("~/.collins.yaml")) then
|
180
|
+
user_config = collins_config_from_file "~/.collins.yaml"
|
181
|
+
if user_config[:collins] then
|
182
|
+
user_config = user_config[:collins]
|
183
|
+
end
|
184
|
+
config.update(:host => user_config[:host]) if config[:host].nil?
|
185
|
+
config.update(:username => user_config[:username]) if config[:username].nil?
|
186
|
+
config.update(:password => user_config[:password]) if config[:password].nil?
|
187
|
+
if config[:timeout] == 30 and user_config[:timeout] then
|
188
|
+
config.update(:timeout => user_config[:timeout].to_i)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
config
|
192
|
+
end
|
193
|
+
|
194
|
+
def collins_config_from_file file
|
195
|
+
symbolize_hash(YAML::load(File.open(File.expand_path(file))))
|
196
|
+
end
|
197
|
+
|
198
|
+
def require_valid_collins_config config
|
199
|
+
begin
|
200
|
+
require_non_empty(config[:host], "collins.host is required")
|
201
|
+
require_non_empty(config[:username], "collins.username is required")
|
202
|
+
require_non_empty(config[:password], "collins.password is required")
|
203
|
+
rescue Exception => e
|
204
|
+
raise CollinsShell::ConfigurationError.new(e.message)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|