class Eco::API::Organization::PresetsFactory

Constants

ABILITIES
INTEGRITY

Public Class Methods

abilities() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 23
def abilities
  @abilities ||= abilities_model.keys
end
abilities_model() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 15
def abilities_model
  @abilities_model ||= JSON.load(File.open(ABILITIES))
end
all_abilities(hash = {}) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 11
def all_abilities(hash = {})
  Hash[abilities.each_with_object(nil).to_a].merge(hash)
end
integrity_model() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 19
def integrity_model
  @integrity_model ||= JSON.load(File.open(INTEGRITY))
end
new(enviro: nil, policy_groups: nil) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 29
def initialize(enviro: nil, policy_groups: nil)
  fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
  @enviro        = enviro
  @policy_groups = policy_groups
end

Public Instance Methods

keys() click to toggle source

@return [Array<String>] all the abilities

# File lib/eco/api/organization/presets_factory.rb, line 36
def keys
  self.class.abilities
end
valid?(preset) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 40
def valid?(preset)
  validate(perset).length == 0
end
validate(preset) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 44
def validate(preset)
  [].tap do |errors|
    if err = preset_errors(preset)
      errors << "{ '#{key}' preset -> #{err}}"
    end
    if err = preset_integrity(preset)
      errors << "{ '#{key}' preset -> #{err}}"
    end
  end
end

Private Instance Methods

abilities_model() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 141
def abilities_model
  self.class.abilities_model
end
abilities_model_inverted() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 131
def abilities_model_inverted
  @abilities_model_inverted ||= abilities_model.each_with_object({}) do |(key, values), out|
    out[key] = values.each_with_object({}) {|v, h| h[v] = true }
  end
end
ability_value_idx(ability, value) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 137
def ability_value_idx(ability, value)
  abilities_model[ability].index(value) || -1
end
compile(*presets) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 57
def compile(*presets)
  presets.compact.reduce({}) do |p1, p2|
    merge(p1, p2)
  end
end
fatal(msg) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 155
def fatal(msg)
  raise msg if !@enviro
  @enviro.logger.fatal(msg)
  raise msg
end
integrity_model() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 123
def integrity_model
  self.class.integrity_model
end
merge(preset1, preset2) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 63
def merge(preset1, preset2)
  keys = preset1.keys | preset2.keys

  abilities_model.each_with_object({}) do |(key, values), result|
    next unless keys.include?(key)
    idx = [
      values.index(preset1[key]),
      values.index(preset2[key])
    ].compact.max
    result[key] = idx && values[idx]
  end
end
policy_groups() click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 145
def policy_groups
  return @policy_groups if @policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
  @policy_groups ||= @enviro&.api&.policy_groups.to_a

  unless @policy_groups.is_a?(Eco::API::Organization::PolicyGroups)
    @policy_groups = Eco::API::Organization::PolicyGroups.new(@policy_groups)
  end
  @policy_groups
end
preset_errors(preset) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 76
def preset_errors(preset)
  return "No preset given" if !preset
  errors = preset.map do |k, v|
    value_exists?(k, v) ? nil : "#{k}:#{v}"
  end.compact
  return " Unknown: {#{errors.join(", ")}}" if errors.length > 0
  nil
end
preset_integrity(preset) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 85
def preset_integrity(preset)
  preset.each_with_object([]) do |(ability, value), errors|
    next unless checks = integrity_model[ability]

    suberrors = []

    checks.each do |check|
      next unless check["value"] == value
      check["conditions"].each do |cond, targets|
        case cond
        when "at_least"
          targets.each do |other, minimum|
            unless (ability_value_idx(other, minimum) <= ability_value_idx(other, preset[other]))
              suberrors << "'#{other}' should be at least '#{minimum}'"
            end
          end
        when "one_of"
          unless targets.any? {|other, expected| preset[other] == expected}
            suberrors << targets.each_with_object([]) do |(other, expected), out|
              out << "'#{other}': '#{expected}'"
            end.join(", ").yield_self do |msg|
              "there should be at least one of: {#{msg}}"
            end
          end
        else
          warn("Unsuported integrity condition statement '#{cond}' in '#{ability}' with level '#{value}'")
        end
      end
    end

    if suberrors.length > 0
      errors << "Incorrect value '#{value}' for '#{ability}' - reasons: {#{suberrors.join(", ")}}"
    end
  end.yield_self do |errors|
    " Integrity errors: { #{errors.join(", ")} }" if errors.length > 0
  end
end
value_exists?(ability, value) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 127
def value_exists?(ability, value)
  abilities_model_inverted.dig(ability, value)
end
warn(msg) click to toggle source
# File lib/eco/api/organization/presets_factory.rb, line 161
def warn(msg)
  raise msg if !@enviro
  @enviro.logger.warn(msg)
end