Created
May 9, 2018 13:58
-
-
Save gswallow/22eb0443d0fe348a9bf9c6d015550ae5 to your computer and use it in GitHub Desktop.
Red Hat Satellite 6 Content Promotion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require 'time' | |
require 'rest-client' | |
require 'json' | |
HOST = '{{ satellite_deployment_hostname_full }}' | |
ORG_NAME = '{{ satellite_deployment_organization }}' | |
DELAYED_ENVS = [ "training", "prod", "fye" ] | |
KEEP = 3 | |
URL = "https://#{HOST}" | |
CV_NAME = 'default' | |
FOREMAN_URL = "#{URL}/api/v2" | |
TASKS_URL = "#{URL}/foreman_tasks/api" | |
KATELLO_URL = "#{URL}/katello/api/v2" | |
USERNAME = 'admin' | |
PASSWORD = File.read('/root/.satellite_password').chomp | |
def make_request(location, method = :get, json_data = {}) | |
location = "#{location}" | |
tries = 10 | |
begin | |
response = RestClient::Request.new( | |
:method => method.to_sym, | |
:url => location, | |
:user => USERNAME, | |
:password => PASSWORD, | |
:headers => { :accept => :json, :content_type => :json }, | |
:payload => JSON.generate(json_data) | |
).execute | |
rescue RestClient::BadRequest => e | |
tries -= 1 | |
if tries > 0 | |
print "retrying..." | |
sleep 3 | |
retry | |
else | |
response = "failed: #{e}" | |
end | |
end | |
JSON.parse(response.to_str) | |
end | |
def poll_task(id) | |
poll_result = make_request("#{TASKS_URL}/tasks/#{id}", :get) | |
while poll_result['state'] != "stopped" do | |
sleep 2 | |
print "." | |
poll_result = make_request("#{TASKS_URL}/tasks/#{id}", :get) | |
end | |
poll_result['result'] | |
end | |
def run_task(path, params = {}) | |
res = poll_task make_request(path, :post, params)['id'] | |
sleep 30 | |
puts res | |
end | |
def delete_task(path, params = {}) | |
res = poll_task make_request(path, :delete, params)['id'] | |
sleep 30 | |
puts res | |
end | |
def order_of(lifecycle_envs = []) | |
order = Array.new | |
lifecycle_envs.each do |e| | |
if e['prior'].nil? | |
order.unshift({'name' => e['name'], 'id' => e['id']}) | |
elsif order.include?(e['prior']['name']) | |
order.insert(order.index(e['prior']['name']) + 1, {'name' => e['name'], 'id' => e['id']}) | |
else | |
order.push({'name' => e['name'], 'id' => e['id']}) | |
end | |
end | |
order.reject! { |e| e['name'] == 'Library' } | |
end | |
def organizations | |
make_request("#{FOREMAN_URL}/organizations", :get)['results'] | |
end | |
def my_org_id | |
organizations.map { |o| o['id'] if o['name'] == ORG_NAME }.first | |
end | |
def content_views | |
make_request("#{KATELLO_URL}/content_views", :get)['results'] | |
end | |
def my_content_view_id | |
content_views.map { |v| v if v['name'] == CV_NAME }.first['id'] | |
end | |
def content_view_versions | |
make_request("#{KATELLO_URL}/content_views/#{my_content_view_id}/", :get)['versions'] | |
end | |
def latest_version_id | |
content_view_versions.sort { |v1, v2| v1['version'].to_f <=> v2['version'].to_f }.last['id'] | |
end | |
def latest_version | |
content_view_versions.sort { |v1, v2| v1['version'].to_f <=> v2['version'].to_f }.last['version'] | |
end | |
def latest_version_published | |
content_view_versions.sort { |v1, v2| v1['version'].to_f <=> v2['version'].to_f }.last['published'] | |
end | |
def latest_version_environment_ids | |
content_view_versions.sort { |v1, v2| v1['version'].to_f <=> v2['version'].to_f }.last['environment_ids'] | |
end | |
def paths | |
make_request("#{KATELLO_URL}/organizations/#{my_org_id}/environments/paths", :get)['results'].first | |
end | |
def lifecycle_environments | |
paths['environments'] | |
end | |
def is_old_enough?(stamp, days) | |
Time.now - (Time.parse stamp) > days * 86400 - 3600 | |
end | |
# ----------v do the things v-------- # | |
# Promote the latest version of the content view to each lifecycle environment, in order, except to Library | |
order_of(lifecycle_environments).each do |e| | |
if is_old_enough?(latest_version_published, 14) || !DELAYED_ENVS.include?(e['name']) | |
if !latest_version_environment_ids.include?(e['id']) | |
print "Promoting version #{latest_version} of #{CV_NAME} to #{e['name']}..." | |
run_task("#{KATELLO_URL}/content_view_versions/#{latest_version_id}/promote", {'environment_id' => e['id']}) | |
else | |
puts "#{e['name']} is already at #{latest_version} of #{CV_NAME}. Skipping." | |
end | |
else | |
puts "Not promoting version #{latest_version} of #{CV_NAME} to #{e['name']} because it is delayed." | |
end | |
end | |
# Publish a new version of the content view if it's older than 28 days | |
if is_old_enough?(latest_version_published, 28) | |
print "Publishing new version of the #{CV_NAME} content view..." | |
run_task("#{KATELLO_URL}/content_views/#{my_content_view_id}/publish") | |
else | |
puts "Not publishing #{CV_NAME} content view because the latest is less than 28 days old" | |
end | |
# Promote the newest version of the content view to test environments, which are not delayed | |
order_of(lifecycle_environments).each do |e| | |
if !DELAYED_ENVS.include?(e['name']) | |
if !latest_version_environment_ids.include?(e['id']) | |
print "Promoting version #{latest_version} of #{CV_NAME} to #{e['name']}..." | |
run_task("#{KATELLO_URL}/content_view_versions/#{latest_version_id}/promote", {'environment_id' => e['id']}) | |
else | |
puts "#{e['name']} is already at #{latest_version} of #{CV_NAME}. Skipping." | |
end | |
end | |
end | |
# Clean up everything except for the last kept versions | |
keep = 0 - KEEP | |
content_view_versions[0..keep].each do |v| | |
print "Deleting version #{v['version']}..." | |
delete_task("#{KATELLO_URL}/content_view_versions/#{v['id']}") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment