mofa 0.5.12 → 0.5.13
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 +4 -4
- data/lib/mofa/cli.rb +3 -6
- data/lib/mofa/cookbook.rb +17 -22
- data/lib/mofa/hostlist.rb +2 -61
- data/lib/mofa/mofa_cmd.rb +12 -12
- data/lib/mofa/provision_cmd.rb +1 -1
- data/lib/mofa/released_cookbook.rb +2 -2
- data/lib/mofa/runlist_map.rb +1 -3
- data/lib/mofa/version.rb +1 -1
- metadata +2 -4
- data/rspec/mofa/hostfile_spec.rb +0 -18
- data/rspec/mofa/test_hostlist.json +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22340c00ac56402d53cb1ed841920ace967951402a866f9ca880c33d25616c73
|
4
|
+
data.tar.gz: 228bdcb23b75e5da076e1f6f5ec80be8e63f2df02eeb828f564666ae566d0502
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f31f027919a1a26cc1bb5eaf973631cc37762d39592dc688948d2ea4f29b5d94909d320ea43a595eb15fa67f262178f6e9024b8e2c91a8745fd5f163d95ef51b
|
7
|
+
data.tar.gz: 92c20936e7dd2b917d6be30d548bf6c6efef8249a51e002788500088cdfeaf0ce4e179c1688d1731b001dc90eb34db1561e88179ca2957ef042f905edd163c07
|
data/lib/mofa/cli.rb
CHANGED
@@ -17,7 +17,6 @@ module Mofa
|
|
17
17
|
|
18
18
|
desc 'provision <cookbook>', 'provisions Targethost(s) using a given cookbook.'
|
19
19
|
method_option :ignore_ping, :type => :boolean, :aliases => '-P'
|
20
|
-
method_option :target, :type => :string, :aliases => '-t'
|
21
20
|
method_option :concrete_target, :type => :string, :aliases => '-T'
|
22
21
|
method_option :runlist, :type => :string, :aliases => '-o'
|
23
22
|
method_option :attributes, :type => :string, :aliases => '-j'
|
@@ -27,17 +26,15 @@ module Mofa
|
|
27
26
|
method_option :ssh_user, :type => :string, :aliases => '-u', :default => 'sccchef'
|
28
27
|
method_option :ssh_keyfile, :type => :string, :aliases => '-i', :default => '~/.ssh/id_rsa_sccchef'
|
29
28
|
method_option :tmp_dir, :type => :string, :aliases => '-w', :default => '~/tmp/mofa'
|
30
|
-
|
29
|
+
method_option :binrepo_base_url, :type => :string, :aliases => '-r'
|
30
|
+
|
31
31
|
def provision(cookbook_name_or_path)
|
32
32
|
set_verbosity
|
33
|
-
|
34
33
|
cookbook_name_or_path ||= '.'
|
35
34
|
|
36
|
-
target_filter = options[:target]
|
37
|
-
|
38
35
|
token = MofaCmd.generate_token
|
39
36
|
|
40
|
-
hostlist = Hostlist.create(
|
37
|
+
hostlist = Hostlist.create(options[:concrete_target])
|
41
38
|
cookbook = Cookbook.create(cookbook_name_or_path, token, options[:override_mofa_secrets])
|
42
39
|
runlist_map = RunlistMap.create(cookbook, hostlist, token, options[:runlist])
|
43
40
|
attributes_map = AttributesMap.create(cookbook, hostlist, token, options[:runlist], options[:attributes])
|
data/lib/mofa/cookbook.rb
CHANGED
@@ -24,16 +24,16 @@ class Cookbook
|
|
24
24
|
cookbook = nil
|
25
25
|
begin
|
26
26
|
case
|
27
|
-
|
28
|
-
|
27
|
+
when cookbook_name_or_path.match(/@/)
|
28
|
+
raise "Did not find released Cookbook #{cookbook_name_or_path}!" unless ReleasedCookbook.exists?(cookbook_name_or_path)
|
29
29
|
|
30
|
-
|
30
|
+
cookbook = ReleasedCookbook.new(cookbook_name_or_path, override_mofa_secrets)
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
else
|
33
|
+
cookbook = SourceCookbook.new(cookbook_name_or_path, override_mofa_secrets)
|
34
34
|
end
|
35
35
|
rescue RuntimeError => e
|
36
|
-
raise
|
36
|
+
raise 'Cookbook not found/detected: ' + e.message
|
37
37
|
end
|
38
38
|
cookbook.token = token
|
39
39
|
cookbook.autodetect_type
|
@@ -43,32 +43,29 @@ class Cookbook
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def autodetect_type
|
46
|
-
env_indicator =
|
47
|
-
|
48
|
-
base_indicator = Mofa::Config.config['cookbook_type_indicator']['base']
|
46
|
+
env_indicator = '^env_.*'
|
47
|
+
base_indicator = '.*_base$'
|
49
48
|
|
50
|
-
say
|
49
|
+
say 'Autodetecting Cookbook Architectural Type...'
|
51
50
|
|
52
51
|
case
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
else
|
60
|
-
@type = 'application'
|
52
|
+
when @name.match(env_indicator)
|
53
|
+
@type = 'env'
|
54
|
+
when @name.match(base_indicator)
|
55
|
+
@type = 'base'
|
56
|
+
else
|
57
|
+
@type = 'application'
|
61
58
|
end
|
62
59
|
say "#{type.capitalize} Cookbook"
|
63
60
|
end
|
64
61
|
|
65
|
-
def say(message =
|
62
|
+
def say(message = '', color = nil, force_new_line = (message.to_s !~ /( |\t)$/))
|
66
63
|
color ||= :green
|
67
64
|
super
|
68
65
|
end
|
69
66
|
|
70
67
|
def ok(detail=nil)
|
71
|
-
text = detail ? "OK, #{detail}." :
|
68
|
+
text = detail ? "OK, #{detail}." : 'OK.'
|
72
69
|
say text, :green
|
73
70
|
end
|
74
71
|
|
@@ -86,6 +83,4 @@ class Cookbook
|
|
86
83
|
exit_code = super(cmd, args.merge(:verbose => verbose))
|
87
84
|
fail "Failed to run #{cmd.inspect}!" unless exit_code == true
|
88
85
|
end
|
89
|
-
|
90
|
-
|
91
86
|
end
|
data/lib/mofa/hostlist.rb
CHANGED
@@ -4,20 +4,10 @@ require 'json'
|
|
4
4
|
|
5
5
|
class Hostlist
|
6
6
|
attr_accessor :list
|
7
|
-
attr_accessor :filter
|
8
|
-
attr_accessor :service_host
|
9
|
-
attr_accessor :service_url
|
10
|
-
attr_accessor :api_key
|
11
7
|
attr_accessor :concrete_target
|
12
8
|
|
13
|
-
def self.create(
|
9
|
+
def self.create(concrete_target)
|
14
10
|
hl = Hostlist.new
|
15
|
-
filter = Mofa::Config.config['service_hostlist_default_filter'] if concrete_target.nil? && filter.nil?
|
16
|
-
service_hostlist_url ||= Mofa::Config.config['service_hostlist_url']
|
17
|
-
hl.filter = filter
|
18
|
-
hl.service_host = Mofa::Config.config['service_hostlist_url'].gsub(/^http:\/\//, '').gsub(/\/.*$/, '').gsub(/:.*$/, '')
|
19
|
-
hl.service_url = service_hostlist_url
|
20
|
-
hl.api_key = Mofa::Config.config['service_hostlist_api_key']
|
21
11
|
hl.concrete_target = concrete_target
|
22
12
|
hl
|
23
13
|
end
|
@@ -30,65 +20,16 @@ class Hostlist
|
|
30
20
|
Hostlist::get_shortname(hostname).gsub(/\d+$/, '')
|
31
21
|
end
|
32
22
|
|
33
|
-
def has_concrete_target
|
34
|
-
return (@concrete_target.nil?) ? false : true
|
35
|
-
end
|
36
|
-
|
37
23
|
def retrieve
|
38
|
-
|
39
|
-
when has_concrete_target
|
40
|
-
@list = [@concrete_target]
|
41
|
-
when @service_url.match(/^http/)
|
42
|
-
fail "Hostlist Service not reachable! (cannot ping #{service_host})" unless up?
|
43
|
-
response = RestClient.get(@service_url, {:params => {:key => api_key}})
|
44
|
-
hosts_list_json = JSON.parse response.body
|
45
|
-
@list = hosts_list_json['data'].collect { |i| i['cname'] }
|
46
|
-
when @service_url.match(/^file:/)
|
47
|
-
json_file = @service_url.gsub(/^file:\/\//, '')
|
48
|
-
if File.exist?(json_file)
|
49
|
-
hosts_list_json = JSON.parse(File.read(json_file))
|
50
|
-
@list = hosts_list_json['data'].collect { |i| i['cname'] }
|
51
|
-
else
|
52
|
-
fail "Hostlist JSON-File not found: #{json_file}"
|
53
|
-
end
|
54
|
-
|
55
|
-
else
|
56
|
-
fail "Hostlist Service Url either has to be a http(s):// or a file:/// Url!"
|
57
|
-
end
|
58
|
-
apply_filter
|
59
|
-
sort_by_domainname
|
24
|
+
@list = [@concrete_target]
|
60
25
|
end
|
61
26
|
|
62
|
-
|
63
27
|
def up?
|
64
28
|
p = Net::Ping::TCP.new(@service_host, 'http')
|
65
29
|
p.ping?
|
66
30
|
end
|
67
31
|
|
68
|
-
def apply_filter
|
69
|
-
unless @filter.nil?
|
70
|
-
if @filter[0] == '/' && @filter[-1] == '/' && @filter.length > 2
|
71
|
-
regex = @filter[1..-2]
|
72
|
-
else
|
73
|
-
# building matcher
|
74
|
-
regex = @filter.gsub(/\*/, '__ASTERISK__')
|
75
|
-
regex = Regexp.escape(regex).gsub(/__ASTERISK__/, '.*')
|
76
|
-
regex = '^' + regex + '$'
|
77
|
-
end
|
78
|
-
@list.select! { |hostname| hostname.match(regex) }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def sort_by_domainname
|
83
|
-
sortable = {}
|
84
|
-
@list.each do |hostname|
|
85
|
-
sortable.store(hostname.split(/\./).reverse.join('.'), hostname)
|
86
|
-
end
|
87
|
-
@list = sortable.keys.sort.collect { |s| sortable[s] }
|
88
|
-
end
|
89
|
-
|
90
32
|
def filter_by_runlist_map(runlist_map)
|
91
33
|
@list.select! { |hostname| runlist_map.mp.key?(hostname) }
|
92
34
|
end
|
93
|
-
|
94
35
|
end
|
data/lib/mofa/mofa_cmd.rb
CHANGED
@@ -17,42 +17,42 @@ class MofaCmd
|
|
17
17
|
|
18
18
|
# @abstract
|
19
19
|
def prepare
|
20
|
-
raise RuntimeError,
|
20
|
+
raise RuntimeError, 'must be implemented'
|
21
21
|
end
|
22
22
|
|
23
23
|
# @abstract
|
24
24
|
def execute(_ssh_port)
|
25
|
-
raise RuntimeError,
|
25
|
+
raise RuntimeError, 'must be implemented'
|
26
26
|
end
|
27
27
|
|
28
28
|
# @abstract
|
29
29
|
def cleanup
|
30
|
-
raise RuntimeError,
|
30
|
+
raise RuntimeError, 'must be implemented'
|
31
31
|
end
|
32
32
|
|
33
33
|
def ssh_exec!(ssh, command)
|
34
|
-
stdout_data =
|
35
|
-
stderr_data =
|
34
|
+
stdout_data = ''
|
35
|
+
stderr_data = ''
|
36
36
|
exit_code = nil
|
37
37
|
exit_signal = nil
|
38
38
|
ssh.open_channel do |channel|
|
39
|
-
channel.exec(command) do |
|
39
|
+
channel.exec(command) do |_ch, success|
|
40
40
|
unless success
|
41
41
|
abort "FAILED: couldn't execute command (ssh.channel.exec)"
|
42
42
|
end
|
43
|
-
channel.on_data do |
|
44
|
-
stdout_data+=data
|
43
|
+
channel.on_data do |_ch, data|
|
44
|
+
stdout_data += data
|
45
45
|
end
|
46
46
|
|
47
|
-
channel.on_extended_data do |
|
48
|
-
stderr_data+=data
|
47
|
+
channel.on_extended_data do |_ch, _type, data|
|
48
|
+
stderr_data += data
|
49
49
|
end
|
50
50
|
|
51
|
-
channel.on_request(
|
51
|
+
channel.on_request('exit-status') do |_ch, data|
|
52
52
|
exit_code = data.read_long
|
53
53
|
end
|
54
54
|
|
55
|
-
channel.on_request(
|
55
|
+
channel.on_request('exit-signal') do |_ch, data|
|
56
56
|
exit_signal = data.read_long
|
57
57
|
end
|
58
58
|
end
|
data/lib/mofa/provision_cmd.rb
CHANGED
@@ -207,7 +207,7 @@ class ProvisionCmd < MofaCmd
|
|
207
207
|
end
|
208
208
|
Net::SSH.start(hostname, ssh_user, keys: [ssh_keyfile], port: ssh_port, use_agent: false, verbose: :error) do |ssh|
|
209
209
|
snapshot_or_release = cookbook.is_a?(SourceCookbook) ? 'snapshot' : 'release'
|
210
|
-
out = ssh_exec!(ssh, "sudo chown -R #{
|
210
|
+
out = ssh_exec!(ssh, "sudo chown -R #{ssh_user}.#{ssh_user} #{solo_dir}")
|
211
211
|
puts "ERROR (#{out[0]}): #{out[2]}" if out[0] != 0
|
212
212
|
out = ssh_exec!(ssh, '[ -d /var/lib/mofa ] || sudo mkdir /var/lib/mofa')
|
213
213
|
puts "ERROR (#{out[0]}): #{out[2]}" if out[0] != 0
|
@@ -9,7 +9,7 @@ class ReleasedCookbook < Cookbook
|
|
9
9
|
|
10
10
|
def self.exists?(cookbook_name_or_path)
|
11
11
|
nv = get_name_and_version(cookbook_name_or_path)
|
12
|
-
url = "#{Mofa::
|
12
|
+
url = "#{Mofa::CLI::binrepo_base_url}/#{nv['name']}/#{nv['version']}/#{nv['name']}_#{nv['version']}-full.tar.gz"
|
13
13
|
puts "Checking if cookbook exists: #{url}"
|
14
14
|
RestClient.head(url)
|
15
15
|
end
|
@@ -124,7 +124,7 @@ class ReleasedCookbook < Cookbook
|
|
124
124
|
|
125
125
|
def set_cookbooks_url
|
126
126
|
say 'Using remote URI as cookbooks_url: '
|
127
|
-
@cookbooks_url = "#{Mofa::
|
127
|
+
@cookbooks_url = "#{Mofa::CLI::binrepo_base_url}/#{@name}/#{@version}/#{@name}_#{@version}-full.tar.gz"
|
128
128
|
say "#{@cookbooks_url}"
|
129
129
|
end
|
130
130
|
|
data/lib/mofa/runlist_map.rb
CHANGED
@@ -33,7 +33,7 @@ class RunlistMap
|
|
33
33
|
end
|
34
34
|
else
|
35
35
|
hostlist.list.each do |hostname|
|
36
|
-
@mp.store(hostname,
|
36
|
+
@mp.store(hostname, option_runlist)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -51,7 +51,6 @@ class RunlistMap
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
55
54
|
end
|
56
55
|
|
57
56
|
def set_default_runlist_for_every_host
|
@@ -62,5 +61,4 @@ class RunlistMap
|
|
62
61
|
end
|
63
62
|
end
|
64
63
|
end
|
65
|
-
|
66
64
|
end
|
data/lib/mofa/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mofa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Birk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -229,8 +229,6 @@ files:
|
|
229
229
|
- lib/mofa/upload_cmd.rb
|
230
230
|
- lib/mofa/version.rb
|
231
231
|
- mofa.gemspec
|
232
|
-
- rspec/mofa/hostfile_spec.rb
|
233
|
-
- rspec/mofa/test_hostlist.json
|
234
232
|
homepage: https://github.com/pingworks/mofa
|
235
233
|
licenses: []
|
236
234
|
metadata: {}
|
data/rspec/mofa/hostfile_spec.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'mofa/hostlist'
|
2
|
-
require 'mofa/config'
|
3
|
-
|
4
|
-
describe Hostlist do
|
5
|
-
before do
|
6
|
-
Mofa::Config.load
|
7
|
-
|
8
|
-
end
|
9
|
-
it "should initialize" do
|
10
|
-
hostlist = Hostlist.create("/.*/", "file://rspec/mofa/test_hostlist.json")
|
11
|
-
hostlist != nil
|
12
|
-
end
|
13
|
-
it "should retrieve" do
|
14
|
-
hostlist = Hostlist.create("/.*/", "file://rspec/mofa/test_hostlist.json")
|
15
|
-
puts hostlist.retrieve.count
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|