Skip to content

Instantly share code, notes, and snippets.

@kimburgess
Created November 19, 2018 04:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kimburgess/ca98c1a05de7ec67222d989dea040174 to your computer and use it in GitHub Desktop.
Save kimburgess/ca98c1a05de7ec67222d989dea040174 to your computer and use it in GitHub Desktop.
Example system and module driver state scripts
# frozen_string_literal: true
# On/off switch for modules, systems and zones.
namespace :set_running do
UAT_ZONE_ID = 'zone-dh6ONGpV-p'
DEVICE_MANAGEMENT_ZONE_ID = 'zone-ZYB31rEaOJ'
# ------------------------------
# Helpers
# Re-attempting model updates in case bad things happen
def save!(object, max_attempts = 8)
tries ||= max_attempts
object.save!
rescue => e
puts "error: #{e.message} -- #{object.errors.messages}"
if (tries -= 1) > 0
sleep 1
retry
else
puts "FAILED TO CREATE #{object}"
return
end
end
# Provide a module start / stop proc for passing to enumerators below
def set_running(state)
proc do |mod|
mod.running = state
save! mod
end
end
# Map a string to a boolean value
def to_bool(str)
constants = Class.new.extend ::Orchestrator::Constants
if constants.is_affirmative? str
true
elsif constants.is_negatory? str
false
else
raise ArgumentError, "\"#{str}\" is not boolean-ish"
end
end
# Activate modules based on system -> zone membership
def activate_systems_by_zone(zone_id, invert: false, ignore: [])
zone = ::Orchestrator::Zone.find_by_id zone_id
if invert
puts "Deactivating all systems in #{zone.name}, activating others"
else
puts "Activating all systems in #{zone.name}, deactivating others"
end
ignore = Array.wrap ignore
activated = []
deactivated = []
::Orchestrator::ControlSystem.all.stream do |sys|
next unless (sys.zones & ignore).empty?
if sys.zones.include?(zone_id) ^ invert
running_state = true
activated << sys.id
else
running_state = false
deactivated << sys.id
end
modules = ::Orchestrator::Module.find_by_id sys.modules
modules = Array.wrap(modules)
modules.each(&set_running(running_state))
end
activated.sort!
deactivated.sort!
puts "\nActivated:"
puts activated.join "\n"
puts "\nDeactivated:"
puts deactivated.join "\n"
[activated, deactivated]
end
# ------------------------------
# Tasks
desc 'Set the running state of all modules based on a specific dependency'
task(:modules, [:dependency_id, :state] => [:environment]) do |_, args|
dependency_id = args[:dependency_id]
state = to_bool args[:state]
dependency = ::Orchestrator::Dependency.find_by_id dependency_id
puts "#{state ? '' : 'de'}activating all instances of #{dependency.name}"
dependency.modules.stream(&set_running(state))
end
desc 'Switch all modules in systems from a specific zone on or off'
task(:zone, [:zone_id, :state] => [:environment]) do |_, args|
zone_id = args[:zone_id]
state = to_bool args[:state]
zone = ::Orchestrator::Zone.find_by_id zone_id
puts "#{state ? '' : 'de'}activating modules in systems from #{zone.name}"
zone.systems.stream do |sys|
modules = ::Orchestrator::Module.find_by_id sys.modules
modules = Array.wrap(modules)
modules.each(&set_running(state))
end
end
desc 'Activate all systems in the UAT zone and deactivate others'
task(uat: :environment) do
activate_systems_by_zone UAT_ZONE_ID, ignore: DEVICE_MANAGEMENT_ZONE_ID
end
desc 'Deactivate all systems in the UAT zone and activate others'
task(prod: :environment) do
activate_systems_by_zone UAT_ZONE_ID, invert: true, ignore: DEVICE_MANAGEMENT_ZONE_ID
end
desc 'Populate the UAT zone with all currently running systems'
task(populate_uat: :environment) do
::Orchestrator::ControlSystem.all.stream do |sys|
modules = ::Orchestrator::Module.find_by_id sys.modules
modules = Array.wrap modules
# Denote a system as 'off' if all modules are stopped
system_off = modules.all? { |mod| !mod.running }
if system_off
sys.zones -= [UAT_ZONE_ID]
else
sys.zones |= [UAT_ZONE_ID]
end
save! sys
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment