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.
@@ -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,9 @@
1
+ #! /bin/sh
2
+
3
+ cat <<EOF >> /etc/subversion/servers
4
+ http-proxy-host = $svn_proxy_host
5
+ http-proxy-port = $svn_proxy_port
6
+ http-proxy-username = $svn_proxy_user
7
+ http-proxy-password = $svn_proxy_password
8
+ EOF
9
+
@@ -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
+