Skip to content

Instantly share code, notes, and snippets.

@gswallow
Created May 9, 2018 13:58
Show Gist options
  • Save gswallow/22eb0443d0fe348a9bf9c6d015550ae5 to your computer and use it in GitHub Desktop.
Save gswallow/22eb0443d0fe348a9bf9c6d015550ae5 to your computer and use it in GitHub Desktop.
Red Hat Satellite 6 Content Promotion
#!/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