Skip to content

Commit a2f449e

Browse files
Merge pull request #196 from puppetlabs/SOLARCH-558
SOLARCH-558 code sync status task
2 parents 42b730a + d329877 commit a2f449e

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

tasks/code_sync_status.json

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"puppet_task_version": 1,
3+
"supports_noop": false,
4+
"description": "A task to confirm code is in sync accross the cluster for clusters with code manager configured",
5+
"parameters": {
6+
"environments": {
7+
"type": "Array",
8+
"description": "A list of environments to check, pass a single value of all for all",
9+
"default": ["all"]
10+
}
11+
},
12+
"input_method": "stdin"
13+
}

tasks/code_sync_status.rb

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/opt/puppetlabs/puppet/bin/ruby
2+
3+
# Puppet Task Name: code_sync_status
4+
require 'net/https'
5+
require 'uri'
6+
require 'json'
7+
require 'puppet'
8+
9+
# CodeSyncStatus task class
10+
class CodeSyncStatus
11+
def initialize(params)
12+
@params = params
13+
end
14+
15+
def execute!
16+
puts sync_status.to_json
17+
end
18+
19+
private
20+
21+
def https_client
22+
client = Net::HTTP.new('localhost', '8140')
23+
client.use_ssl = true
24+
client.cert = @cert ||= OpenSSL::X509::Certificate.new(File.read(Puppet.settings[:hostcert]))
25+
client.key = @key ||= OpenSSL::PKey::RSA.new(File.read(Puppet.settings[:hostprivkey]))
26+
client.verify_mode = OpenSSL::SSL::VERIFY_NONE
27+
client
28+
end
29+
30+
def api_status
31+
status = https_client
32+
# Only debug level includes code sync details
33+
status_request = Net::HTTP::Get.new('/status/v1/services?level=debug')
34+
JSON.parse(status.request(status_request).body)
35+
end
36+
37+
def check_environment_list(environments, request_environments)
38+
environmentstocheck = []
39+
# If all was passed as an argument we check all visible environments
40+
if request_environments.any? { |s| s.casecmp('all') == 0 }
41+
environmentstocheck = environments
42+
# Else check each requested environment to confirm its a visible environment
43+
else
44+
request_environments.each do |environment|
45+
environments.any? { |s| s.casecmp(environment.to_s) == 0 } || raise("Environment #{environment} is not visible and will not be checked")
46+
environmentstocheck << environment
47+
end
48+
end
49+
environmentstocheck
50+
end
51+
52+
def check_environment_code(environment, servers, status_call)
53+
# Find the commit ID of the environment according to the file sync service note expected message is of the format
54+
# code-manager deploy signature: '93027145096d9f1e0b716b20b8129618d0a2c7e2'
55+
primarycommit = status_call.dig('file-sync-storage-service',
56+
'status',
57+
'repos',
58+
'puppet-code',
59+
'submodules',
60+
environment.to_s,
61+
'latest_commit',
62+
'message').split("'").last
63+
results = {}
64+
results['latest_commit'] = primarycommit
65+
results['servers'] = {}
66+
servers.each do |server|
67+
results['servers'][server] = {}
68+
# Find the commit ID of the server we are checking for this environment note expected message is of the format
69+
# code-manager deploy signature: '93027145096d9f1e0b716b20b8129618d0a2c7e2'
70+
servercommit = status_call.dig('file-sync-storage-service',
71+
'status',
72+
'clients',
73+
server.to_s,
74+
'repos',
75+
'puppet-code',
76+
'submodules',
77+
environment.to_s,
78+
'latest_commit',
79+
'message').split("'").last
80+
results['servers'][server]['commit'] = servercommit
81+
# Check if it matches and if not mark the environment not in sync on an environment
82+
results['servers'][server]['sync'] = servercommit == primarycommit
83+
end
84+
results['sync'] = results['servers'].all? { |_k, v| v['sync'] == true }
85+
results
86+
end
87+
88+
def sync_status
89+
status_call = api_status
90+
# Get list of servers from filesync service
91+
servers = status_call['file-sync-storage-service']['status']['clients'].keys
92+
# Get list of environments from filesync service
93+
environments = status_call['file-sync-storage-service']['status']['repos']['puppet-code']['submodules'].keys
94+
# Process this list of environments and validate against visible environments
95+
environmentstocheck = check_environment_list(environments, @params['environments'])
96+
results = {}
97+
# For each environment get the syncronisation information of the servers
98+
environmentstocheck.each do |environment|
99+
results[environment] = check_environment_code(environment, servers, status_call)
100+
end
101+
# Confirm are all environments being checked in sync
102+
results['sync'] = results.all? { |_k, v| v['sync'] == true }
103+
results
104+
end
105+
end
106+
# Run the task unless an environment flag has been set, signaling not to. The
107+
# environment flag is used to disable auto-execution and enable Ruby unit
108+
# testing of this task.
109+
unless ENV['RSPEC_UNIT_TEST_MODE']
110+
Puppet.initialize_settings
111+
task = CodeSyncStatus.new(JSON.parse(STDIN.read))
112+
task.execute!
113+
end

0 commit comments

Comments
 (0)