Class: Krane::RolloutConditions

Inherits:
Object
  • Object
show all
Defined in:
lib/krane/rollout_conditions.rb

Constant Summary collapse

VALID_FAILURE_CONDITION_KEYS =
[:path, :value, :error_msg_path, :custom_error_msg]
VALID_SUCCESS_CONDITION_KEYS =
[:path, :value]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conditions) ⇒ RolloutConditions

Returns a new instance of RolloutConditions.



56
57
58
59
# File 'lib/krane/rollout_conditions.rb', line 56

def initialize(conditions)
  @success_conditions = conditions.fetch(:success_conditions, [])
  @failure_conditions = conditions.fetch(:failure_conditions, [])
end

Class Method Details

.default_conditionsObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/krane/rollout_conditions.rb', line 37

def default_conditions
  {
    success_conditions: [
      {
        path: JsonPath.new('$.status.conditions[?(@.type == "Ready")].status'),
        value: "True",
      },
    ],
    failure_conditions: [
      {
        path: JsonPath.new('$.status.conditions[?(@.type == "Failed")].status'),
        value: "True",
        error_msg_path: JsonPath.new('$.status.conditions[?(@.type == "Failed")].message'),
      },
    ],
  }
end

.from_annotation(conditions_string) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/krane/rollout_conditions.rb', line 11

def from_annotation(conditions_string)
  return new(default_conditions) if conditions_string.downcase.strip == "true"

  conditions = JSON.parse(conditions_string).slice('success_conditions', 'failure_conditions')
  conditions.deep_symbolize_keys!

  # Create JsonPath objects
  conditions[:success_conditions]&.each do |query|
    query.slice!(*VALID_SUCCESS_CONDITION_KEYS)
    query[:path] = JsonPath.new(query[:path]) if query.key?(:path)
  end
  conditions[:failure_conditions]&.each do |query|
    query.slice!(*VALID_FAILURE_CONDITION_KEYS)
    query[:path] = JsonPath.new(query[:path]) if query.key?(:path)
    query[:error_msg_path] = JsonPath.new(query[:error_msg_path]) if query.key?(:error_msg_path)
  end

  new(conditions)
rescue JSON::ParserError => e
  raise RolloutConditionsError, "Rollout conditions are not valid JSON: #{e}"
rescue StandardError => e
  raise RolloutConditionsError,
    "Error parsing rollout conditions. " \
    "This is most likely caused by an invalid JsonPath expression. Failed with: #{e}"
end

Instance Method Details

#failure_messages(instance_data) ⇒ Object



73
74
75
76
77
78
# File 'lib/krane/rollout_conditions.rb', line 73

def failure_messages(instance_data)
  @failure_conditions.map do |query|
    next unless query[:path].first(instance_data) == query[:value]
    query[:custom_error_msg].presence || query[:error_msg_path]&.first(instance_data)
  end.compact
end

#rollout_failed?(instance_data) ⇒ Boolean

Returns:

  • (Boolean)


67
68
69
70
71
# File 'lib/krane/rollout_conditions.rb', line 67

def rollout_failed?(instance_data)
  @failure_conditions.any? do |query|
    query[:path].first(instance_data) == query[:value]
  end
end

#rollout_successful?(instance_data) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
64
65
# File 'lib/krane/rollout_conditions.rb', line 61

def rollout_successful?(instance_data)
  @success_conditions.all? do |query|
    query[:path].first(instance_data) == query[:value]
  end
end

#validate!Object



80
81
82
83
84
# File 'lib/krane/rollout_conditions.rb', line 80

def validate!
  errors = validate_conditions(@success_conditions, 'success_conditions')
  errors += validate_conditions(@failure_conditions, 'failure_conditions', required: false)
  raise RolloutConditionsError, errors.join(", ") unless errors.empty?
end