admiral-check 0.0.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/CHANGELOG.md +6 -0
- data/Gemfile +3 -0
- data/LICENSE +16 -0
- data/README.md +20 -0
- data/Rakefile +2 -0
- data/admiral-check.gemspec +28 -0
- data/bin/admiral +10 -0
- data/lib/admiral/config.rb +96 -0
- data/lib/admiral/core.rb +154 -0
- data/lib/admiral/docker.rb +368 -0
- data/lib/admiral/layer.rb +186 -0
- data/lib/admiral/layers/admiral.build.sh.rb +40 -0
- data/lib/admiral/layers/admiral.exemple.test.rb +25 -0
- data/lib/admiral/layers/admiral.puppet.apply.rb +31 -0
- data/lib/admiral/layers/admiral.svn.proxy.rb +42 -0
- data/lib/admiral/layers/admiral.svn.proxy.sh +9 -0
- data/lib/admiral/layers/admiral.svn.puppet.cookbook.rb +47 -0
- data/lib/admiral/layers/admiral.svn.puppet.manifest.rb +35 -0
- data/lib/admiral/layers/admiral.test.chef.install.rb +26 -0
- data/lib/admiral/layers/admiral.test.serverspec.install.rb +37 -0
- data/lib/admiral/layers/admiral.test.serverspec.install.sh +6 -0
- data/lib/admiral/layers/admiral.test.serverspec.run.rb +37 -0
- data/lib/admiral/layers/admiral.test.serverspec.run.sh +5 -0
- data/lib/admiral/layers/admiral.test.serverspec.upload.d/.rspec +4 -0
- data/lib/admiral/layers/admiral.test.serverspec.upload.d/Rakefile +17 -0
- data/lib/admiral/layers/admiral.test.serverspec.upload.rb +33 -0
- data/lib/admiral/shell.rb +30 -0
- data/lib/admiral/version.rb +19 -0
- metadata +187 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/config'
|
6
|
+
require 'net/ssh'
|
7
|
+
require 'net/scp'
|
8
|
+
require 'pp'
|
9
|
+
|
10
|
+
module Admiral
|
11
|
+
|
12
|
+
module Layer
|
13
|
+
def self.uid_to_name(uid)
|
14
|
+
class_name = ''
|
15
|
+
|
16
|
+
l = uid.split('.')
|
17
|
+
l.each do |word|
|
18
|
+
class_name << word.capitalize
|
19
|
+
end
|
20
|
+
|
21
|
+
return class_name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class LayerBase
|
26
|
+
|
27
|
+
def self.inherited(subclass)
|
28
|
+
file = caller.first[/^[^:]+/]
|
29
|
+
$uid = File.basename(file,File.extname(file))
|
30
|
+
$location = File.dirname(file)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(description, config, ipaddress)
|
34
|
+
@description = description
|
35
|
+
@config = config
|
36
|
+
@ipaddress = ipaddress
|
37
|
+
@parameters = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_parameter(name, description)
|
41
|
+
parameter = { 'name'=>name, 'description'=>description }
|
42
|
+
@parameters << parameter
|
43
|
+
end
|
44
|
+
|
45
|
+
def show_information
|
46
|
+
puts "Layer UID: #{$uid}"
|
47
|
+
puts "Description: #{@description}"
|
48
|
+
if @parameters.count > 0
|
49
|
+
puts "Paramaters:"
|
50
|
+
@parameters.each do | parameter |
|
51
|
+
puts " #{parameter['name']} / #{parameter['description']}"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
puts "No paramater"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def verify ()
|
60
|
+
@parameters.each do | parameter |
|
61
|
+
if not @config.key?(parameter['name'])
|
62
|
+
STDERR.puts "Layer #{$uid} requires the parameter #{parameter['name']}, but it is not found"
|
63
|
+
return false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
|
69
|
+
def run()
|
70
|
+
puts "--- #{@description} ---"
|
71
|
+
username = @config['username']
|
72
|
+
|
73
|
+
layer_location = $location
|
74
|
+
layer_uid = $uid
|
75
|
+
|
76
|
+
layer_folder = "#{layer_location}/#{layer_uid}.d"
|
77
|
+
layer_shell = "#{layer_location}/#{layer_uid}.sh"
|
78
|
+
layer_perl = "#{layer_location}/#{layer_uid}.pl"
|
79
|
+
layer_remote_dir = "/tmp/#{username}/"
|
80
|
+
|
81
|
+
if File.exists?(layer_folder)
|
82
|
+
upload(layer_folder, layer_remote_dir)
|
83
|
+
end
|
84
|
+
|
85
|
+
if File.exists?(layer_shell)
|
86
|
+
upload(layer_shell, layer_remote_dir)
|
87
|
+
end
|
88
|
+
|
89
|
+
if File.exists?(layer_perl)
|
90
|
+
upload(layer_perl, layer_remote_dir)
|
91
|
+
end
|
92
|
+
|
93
|
+
begin
|
94
|
+
success = do_action()
|
95
|
+
rescue Interrupt
|
96
|
+
STDERR.puts "Layer interrupted"
|
97
|
+
return false
|
98
|
+
rescue Errno::EACCES, Errno::ENOENT, Errno::ECONNREFUSED, IOError => e
|
99
|
+
STDERR.puts "Layer has error : #{e.message}"
|
100
|
+
return false
|
101
|
+
rescue Net::SSH::AuthenticationFailed
|
102
|
+
STDERR.puts "Layer has error : SSH - Authentication failed"
|
103
|
+
return false
|
104
|
+
end
|
105
|
+
|
106
|
+
return success
|
107
|
+
end
|
108
|
+
|
109
|
+
def do_action()
|
110
|
+
STDERR.puts "do_action must be implemented"
|
111
|
+
return false
|
112
|
+
end
|
113
|
+
|
114
|
+
def run_ssh_command(command, options = {})
|
115
|
+
username = @config['username']
|
116
|
+
keyfile = @config['keyfile']
|
117
|
+
proxy_url = @config['proxy_url']
|
118
|
+
allow_proxy = options.fetch(:allow_proxy, false)
|
119
|
+
env = options.fetch(:env, nil)
|
120
|
+
|
121
|
+
env_array = []
|
122
|
+
cmd = ""
|
123
|
+
|
124
|
+
if allow_proxy and proxy_url
|
125
|
+
cmd << %Q[export http_proxy="#{proxy_url}";]
|
126
|
+
cmd << %Q[export https_proxy=$http_proxy;]
|
127
|
+
end
|
128
|
+
|
129
|
+
cmd << command
|
130
|
+
|
131
|
+
ssh_cmd = ""
|
132
|
+
|
133
|
+
if not env.nil?
|
134
|
+
env.each do |key, value|
|
135
|
+
ENV[key] = value
|
136
|
+
env_array << key
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
ssh_cmd << "sudo -E sh -c '#{cmd}'"
|
141
|
+
|
142
|
+
Net::SSH.start(@ipaddress, username, :host_key => "ssh-rsa", :keys => [ keyfile ], :user_known_hosts_file => '/dev/null', :send_env => env_array) do |ssh|
|
143
|
+
|
144
|
+
ssh.open_channel do |channel|
|
145
|
+
channel.exec(ssh_cmd) do |ch, success|
|
146
|
+
unless success
|
147
|
+
STDERR.puts "FAILED: couldn't execute command (#{command})"
|
148
|
+
return false
|
149
|
+
end
|
150
|
+
|
151
|
+
channel.on_data do |ch, data|
|
152
|
+
puts data
|
153
|
+
end
|
154
|
+
|
155
|
+
channel.on_extended_data do |ch, type, data|
|
156
|
+
STDERR.puts data
|
157
|
+
end
|
158
|
+
|
159
|
+
channel.on_request("exit-status") do |ch,data|
|
160
|
+
exit_code = data.read_long
|
161
|
+
if exit_code > 0
|
162
|
+
STDERR.puts "FAILED: command (#{command}) has failed"
|
163
|
+
return exit_code
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
ssh.loop
|
170
|
+
return 0
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def upload(local, remote)
|
175
|
+
|
176
|
+
username = @config['username']
|
177
|
+
keyfile = @config['keyfile']
|
178
|
+
|
179
|
+
Net::SCP.upload!(@ipaddress, username,
|
180
|
+
local, remote,
|
181
|
+
:recursive => true,
|
182
|
+
:ssh => { :host_key => "ssh-rsa", :keys => [ keyfile ], :user_known_hosts_file => '/dev/null' })
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
|
7
|
+
module Admiral
|
8
|
+
module Layers
|
9
|
+
class AdmiralBuildSh < Admiral::LayerBase
|
10
|
+
def initialize(config, ipaddress)
|
11
|
+
description = "Executing build script"
|
12
|
+
|
13
|
+
super(description, config, ipaddress)
|
14
|
+
add_parameter('build_script', 'Script file for build (ex: bootstap.sh)')
|
15
|
+
add_parameter('build_env', 'Hash of environmental variables (ex: {"param1"=>"value1", "param2"=>"value2"} )')
|
16
|
+
end
|
17
|
+
|
18
|
+
def do_action()
|
19
|
+
username = @config['username']
|
20
|
+
build_script = @config['build_script']
|
21
|
+
build_env = @config['build_env']
|
22
|
+
|
23
|
+
work_dir = "/tmp/#{username}/"
|
24
|
+
|
25
|
+
if not File.exists?(build_script)
|
26
|
+
STDERR.puts "File #{build_script} not found"
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
upload(build_script, work_dir)
|
31
|
+
|
32
|
+
cmd = %Q[bash /tmp/#{username}/#{build_script}]
|
33
|
+
|
34
|
+
rc = run_ssh_command(cmd, :env => build_env)
|
35
|
+
return (rc == 0)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
|
7
|
+
module Admiral
|
8
|
+
module Layers
|
9
|
+
class AdmiralExempleTest < Admiral::LayerBase
|
10
|
+
def initialize(config, ipaddress)
|
11
|
+
description = "A simple test"
|
12
|
+
|
13
|
+
super(description, config, ipaddress)
|
14
|
+
end
|
15
|
+
|
16
|
+
def do_action()
|
17
|
+
cmd = "touch /tmp/simple-test"
|
18
|
+
run_ssh_command(cmd)
|
19
|
+
|
20
|
+
return true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
|
7
|
+
module Admiral
|
8
|
+
module Layers
|
9
|
+
class AdmiralPuppetApply < Admiral::LayerBase
|
10
|
+
def initialize(config, ipaddress)
|
11
|
+
description = "Applying cookbooks"
|
12
|
+
|
13
|
+
super(description, config, ipaddress)
|
14
|
+
add_parameter('manifest', 'Manifest file (ex: prod.pp)')
|
15
|
+
end
|
16
|
+
|
17
|
+
def do_action
|
18
|
+
|
19
|
+
manifest = @config['manifest']
|
20
|
+
manifests_dir = '/var/lib/puppet/manifests'
|
21
|
+
modules_dir = '/var/lib/puppet/modules'
|
22
|
+
|
23
|
+
cmd = "puppet apply --verbose --modulepath=#{modules_dir} #{manifests_dir}/#{manifest}"
|
24
|
+
|
25
|
+
rc = run_ssh_command(cmd, :allow_proxy => false)
|
26
|
+
return (rc == 0)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
|
7
|
+
module Admiral
|
8
|
+
module Layers
|
9
|
+
class AdmiralSvnProxy < Admiral::LayerBase
|
10
|
+
def initialize(config, ipaddress)
|
11
|
+
description = "Configuring proxy for SVN"
|
12
|
+
|
13
|
+
super(description, config, ipaddress)
|
14
|
+
add_parameter('svn_proxy_host', 'Hostname of the proxy needed to access to svn (ex: proxy.domain.com )')
|
15
|
+
add_parameter('svn_proxy_port', 'Port of the proxy (ex: 80)')
|
16
|
+
add_parameter('svn_proxy_user', 'Username for the proxy (ex: user)')
|
17
|
+
add_parameter('svn_proxy_password', 'Password for the proxy (ex: passwd)')
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_action
|
21
|
+
svn_proxy_host = @config['svn_proxy_host']
|
22
|
+
svn_proxy_port = @config['svn_proxy_port']
|
23
|
+
svn_proxy_user = @config['svn_proxy_user']
|
24
|
+
svn_proxy_password = @config['svn_proxy_password']
|
25
|
+
username = @config['username']
|
26
|
+
|
27
|
+
env = {
|
28
|
+
'svn_proxy_host' => svn_proxy_host,
|
29
|
+
'svn_proxy_port' => svn_proxy_port,
|
30
|
+
'svn_proxy_user' => svn_proxy_user,
|
31
|
+
'svn_proxy_password' => svn_proxy_password,
|
32
|
+
}
|
33
|
+
|
34
|
+
cmd = "/tmp/#{username}/#{$uid}.sh"
|
35
|
+
|
36
|
+
rc = run_ssh_command(cmd, :env => env)
|
37
|
+
return (rc == 0)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
require 'admiral/shell'
|
7
|
+
|
8
|
+
module Admiral
|
9
|
+
module Layers
|
10
|
+
class AdmiralSvnPuppetCookbook < Admiral::LayerBase
|
11
|
+
def initialize(config, ipaddress)
|
12
|
+
description = "Retrieving cookbooks for applications from SVN"
|
13
|
+
|
14
|
+
super(description, config, ipaddress)
|
15
|
+
add_parameter('svn_cookbook_base_url', 'Root URL where are located the cookbooks in SVN (ex: https://domain.com/puppet-cookbooks)')
|
16
|
+
add_parameter('svn_user', 'Username for SVN')
|
17
|
+
add_parameter('svn_password', 'Password for SVN')
|
18
|
+
add_parameter('applications', 'List of hash that contains application code and source branch (ex: [ {"code"=>"appli1", "branch"=>"trunk"}, ] )')
|
19
|
+
end
|
20
|
+
|
21
|
+
def do_action
|
22
|
+
svn_cookbook_base_url = @config['svn_cookbook_base_url']
|
23
|
+
svn_user = @config['svn_user']
|
24
|
+
svn_password = @config['svn_password']
|
25
|
+
|
26
|
+
modules_dir = '/var/lib/puppet/modules/'
|
27
|
+
|
28
|
+
applications = @config['applications']
|
29
|
+
|
30
|
+
applications.each do | application |
|
31
|
+
application_code = application['code']
|
32
|
+
application_branch = application['branch']
|
33
|
+
cmd = "svn co --non-interactive --no-auth-cache #{svn_cookbook_base_url}/#{application_code}/#{application_branch}/ #{modules_dir}/#{application_code} --username=#{svn_user} --password=#{svn_password}; done"
|
34
|
+
puts " - Retrieving cookbook for project #{application_code} from #{application_branch}"
|
35
|
+
|
36
|
+
rc = run_ssh_command(cmd)
|
37
|
+
if rc > 0
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
|
7
|
+
module Admiral
|
8
|
+
module Layers
|
9
|
+
class AdmiralSvnPuppetManifest < Admiral::LayerBase
|
10
|
+
def initialize(config, ipaddress)
|
11
|
+
description = "Retrieving manifest from SVN"
|
12
|
+
|
13
|
+
super(description, config, ipaddress)
|
14
|
+
add_parameter('svn_manifest_base_url', 'Root URL where are located the manifests in SVN (ex: https://domain.com/puppet-manifests)')
|
15
|
+
add_parameter('manifest_source', 'Path after the root URL (ex: production)')
|
16
|
+
add_parameter('svn_user', 'Username for SVN')
|
17
|
+
add_parameter('svn_password', 'Password for SVN')
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_action
|
21
|
+
manifest_source = @config['manifest_source']
|
22
|
+
manifests_dir = '/var/lib/puppet/manifests'
|
23
|
+
svn_manifest_base_url = @config['svn_manifest_base_url']
|
24
|
+
svn_user = @config['svn_user']
|
25
|
+
svn_password = @config['svn_password']
|
26
|
+
|
27
|
+
cmd = "svn co --non-interactive --no-auth-cache #{svn_manifest_base_url}/#{manifest_source} #{manifests_dir} --username=#{svn_user} --password=#{svn_password}"
|
28
|
+
|
29
|
+
rc = run_ssh_command(cmd)
|
30
|
+
return (rc == 0)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'admiral/layer'
|
6
|
+
|
7
|
+
module Admiral
|
8
|
+
module Layers
|
9
|
+
class AdmiralTestChefInstall < Admiral::LayerBase
|
10
|
+
def initialize(config, ipaddress)
|
11
|
+
description = "Get and install chef"
|
12
|
+
|
13
|
+
super(description, config, ipaddress)
|
14
|
+
end
|
15
|
+
|
16
|
+
def do_action()
|
17
|
+
|
18
|
+
cmd = 'wget --no-check-certificate https://www.chef.io/chef/install.sh -O /tmp/install.sh && /bin/bash /tmp/install.sh'
|
19
|
+
|
20
|
+
rc = run_ssh_command(cmd, :allow_proxy => true)
|
21
|
+
return (rc == 0)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|