Skip to content

Commit

Permalink
[core] Add comments on gera and defaults/vars/userVars mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
teo committed Aug 29, 2024
1 parent b68946a commit e5a6051
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
4 changes: 4 additions & 0 deletions common/gera/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
//
// A gera.Map uses a map[string]interface{} as backing store, and it can wrap other gera.Map instances.
// Values in child maps override any value provided by a gera.Map that's wrapped in the hierarchy.
//
// The name is reminiscent of hiera, as in hierarchical, but it was deemed desirable to avoid future confusion with the
// Hiera KV store used by Puppet, a different product altogether, so instead of the ancient Greek root, "gera" comes
// from the Italian root instead where "hi" becomes a soft "g".
package gera

import (
Expand Down
15 changes: 15 additions & 0 deletions core/workflow/rolebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ type roleBase struct {
status SafeStatus
state SafeState

// Defaults, Vars and UserVars are used to store each role's variables.
// Defaults are the lowest priority, Vars are the second highest, and UserVars are the highest.
//
// These use the gera.Map type, which is a wrapper around a map[string]string that provides hierarchical KV store
// semantics.
// The gera.Map logic allows us to ensure that defaults are overridden by vars, and vars by userVars throughout the
// workflow tree, and at the same time that defaults/vars/userVars set in a child role override the relevant values
// set in its parent role.
// The way we do this is by ensuring parent-child (Wrap) relationships between all the Default members in the
// workflow tree, all the Vars members, and all the UserVars members, and then whenever we need to figure out what's
// the consolidated KV map seen from the point of view of a given role, we Flatten each of these three, and then
// Wrap and re-Flatten between the flattened defaults, vars and userVars (see ConsolidatedVarStack). This results in
// a single map, generatable from the POV of any role within the tree.
Defaults *gera.WrapMap[string, string] `yaml:"defaults,omitempty"`
Vars *gera.WrapMap[string, string] `yaml:"vars,omitempty"`
UserVars *gera.WrapMap[string, string] `yaml:"-"`
Expand All @@ -65,6 +78,8 @@ type roleBase struct {
Enabled string `yaml:"enabled,omitempty"`
}

// Needed for the yaml package to correctly unmarshal into gera.Map[string, string] those Defaults and Vars entries from
// a workflow template, that have a !public tag to include input widget metadata.
func kvStoreUnmarshalYAMLWithTags(w gera.Map[string, string], unmarshal func(interface{}) error) error {
nodes := make(map[string]yaml.Node)
err := unmarshal(&nodes)
Expand Down

0 comments on commit e5a6051

Please sign in to comment.