github.com/lyraproj/hiera@v1.0.0-rc4/examples/config_test.go (about)

     1  package examples_test
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/lyraproj/dgo/dgo"
     9  	"github.com/lyraproj/dgo/vf"
    10  	"github.com/lyraproj/hiera/api"
    11  	"github.com/lyraproj/hiera/hiera"
    12  	"github.com/lyraproj/hiera/provider"
    13  	sdk "github.com/lyraproj/hierasdk/hiera"
    14  )
    15  
    16  // sayHello is a very simple "lookup_key" function that just returns the result of concatenating
    17  // the key with the string " world".
    18  func sayHello(_ sdk.ProviderContext, key string) dgo.Value {
    19  	return vf.String(key + ` world`)
    20  }
    21  
    22  /*
    23   Hiera will always use a single "lookup_key" function at the very top, henceforth referred to as the "top level
    24   function". This function determines the hierarchy (or lack thereof) that Hiera uses. This file explains the three such
    25   functions: the sayHello example function, the MuxLookupKey which aggregates other lookup_key functions, and the
    26   ConfigLookupKey which sets up a hierarchy defined in a yaml configuration.
    27  */
    28  
    29  // TestConfig_hardwired utilizes Hiera in the simplest way possible. No configuration file and no options. Just
    30  // a function performing a lookup of a key. In other words, this single function is the entire hierarchy.
    31  func TestConfig_hardwired(t *testing.T) {
    32  	// Use the hiera.DoWithParent to initialize a Hiera Session with the sayHello as the top-level function and
    33  	// perform a lookup.
    34  	//
    35  	// The DoWithParent is meant to be called once and the created context can then be used for any number of lookups that
    36  	// uses the same configuration. The session's life-cycle can be compared to the compiler's life-cycle in puppet.
    37  	hiera.DoWithParent(context.Background(), sayHello, nil, func(hs api.Session) {
    38  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
    39  		if result == nil || `hello world` != result.String() {
    40  			t.Fatalf("unexpected result %v", result)
    41  		}
    42  	})
    43  }
    44  
    45  // TestHelloWorld_semiHardWired uses the "lookup_key" function MuxLookupKey. This function use the configuration
    46  // option LookupKeyFunctions where it expects to find a slice of "lookup_key" functions to use. Those functions form
    47  // top level hierarchy that is configurable from code. Very useful if you for instance want to introduce different
    48  // lookup layers such as "global", "environment", and "module" or in other ways build a complex lookup hierarchy that
    49  // service that goes beyond what can be defined in the yaml configuration.
    50  func TestConfig_semiHardWired(t *testing.T) {
    51  	// Create options valid for this Hiera session.
    52  	// The LookupProvidersKey stores a go slice of Hiera "lookup_key" functions that serve as the top level functions.
    53  	configOptions := vf.Map(provider.LookupKeyFunctions, []sdk.LookupKey{sayHello})
    54  
    55  	// Initialize a Hiera session with the MuxLookupKey as the top-level function and perform a lookup and
    56  	// the created configOptions.
    57  	hiera.DoWithParent(context.Background(), provider.MuxLookupKey, configOptions, func(hs api.Session) {
    58  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
    59  		if result == nil || `hello world` != result.String() {
    60  			t.Fatalf("unexpected result %v", result)
    61  		}
    62  	})
    63  }
    64  
    65  /*
    66   The remaining tests in this file use the ConfigLookupKey provider. This provider will consult the configuration
    67   options HieraRoot, HieraConfigFileName, and HieraConfig to determine the path of the configuration file. Use of
    68   HieraConfig is mutually exclusive with HieraRoot and HieraConfigFileName.
    69  
    70   HieraRoot will default to the current working directory.
    71  
    72   HieraConfigFileName will default to "hiera.yaml".
    73  
    74   If the HieraRoot or HieraConfig are relative paths, they will be considered relative to the current directory.
    75  
    76   The HieraConfigFileName must be relative to the HieraRoot.
    77  */
    78  
    79  // TestHelloWorld_yamlConfig uses the "lookup_key" function ConfigLookupKey and HieraRoot. The ConfigLookupKey is
    80  // the most commonly used top-level function in Hiera. It finds a yaml configuration on disk and then configures
    81  // everything according to the hierarchy specified in that file.
    82  func TestHelloWorld_yamlConfig(t *testing.T) {
    83  	configOptions := vf.Map(api.HieraRoot, `testdata`)
    84  
    85  	// Initialize a Hiera session with the ConfigLookupKey as the top-level function configured using the configOptions.
    86  	hiera.DoWithParent(context.Background(), provider.ConfigLookupKey, configOptions, func(hs api.Session) {
    87  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
    88  		if result == nil || `yaml data says hello` != result.String() {
    89  			t.Fatalf("unexpected result %v", result)
    90  		}
    91  	})
    92  }
    93  
    94  // TestHelloWorld_explicitYamlConfig is similar to TestHelloWorld_yamlConfig but uses HieraConfig
    95  // option to explicitly define the file to use.
    96  func TestHelloWorld_explicitYamlConfig(t *testing.T) {
    97  	configOptions := vf.Map(api.HieraConfig, `testdata/hiera.yaml`)
    98  
    99  	// Initialize a Hiera session with the ConfigLookupKey as the top-level function configured using the configOptions.
   100  	hiera.DoWithParent(context.Background(), provider.ConfigLookupKey, configOptions, func(hs api.Session) {
   101  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
   102  		if result == nil || `yaml data says hello` != result.String() {
   103  			t.Fatalf("unexpected result %v", result)
   104  		}
   105  	})
   106  }
   107  
   108  // TestHelloWorld_explicitYamlConfigEnvironment is similar to TestHelloWorld_yamlConfig but uses HIERA_CONFIGFILE
   109  // environment variable to explicitly define the file to use.
   110  func TestHelloWorld_explicitYamlConfigEnvironment(t *testing.T) {
   111  	configOptions := vf.Map(api.HieraRoot, `testdata`)
   112  	_ = os.Setenv("HIERA_CONFIGFILE", "hiera_env.yaml")
   113  
   114  	// Initialize a Hiera session with the ConfigLookupKey as the top-level function configured using the configOptions.
   115  	hiera.DoWithParent(context.Background(), provider.ConfigLookupKey, configOptions, func(hs api.Session) {
   116  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
   117  		if result == nil || `yaml data says hello` != result.String() {
   118  			t.Fatalf("unexpected result %v", result)
   119  		}
   120  	})
   121  }
   122  
   123  // TestHelloWorld_explicitYamlConfigFile is similar to TestHelloWorld_yamlConfig but uses a combination of
   124  // HieraRoot and HieraConfigFileName option to find the yaml configuration file.
   125  func TestHelloWorld_explicitYamlConfigFile(t *testing.T) {
   126  	configOptions := vf.Map(
   127  		api.HieraRoot, `testdata`,
   128  		api.HieraConfigFileName, `special.yaml`)
   129  
   130  	// Initialize a Hiera session with the ConfigLookupKey as the top-level function configured using the configOptions.
   131  	hiera.DoWithParent(context.Background(), provider.ConfigLookupKey, configOptions, func(hs api.Session) {
   132  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
   133  		if result == nil || `yaml special data says hello` != result.String() {
   134  			t.Fatalf("unexpected result %v", result)
   135  		}
   136  	})
   137  }
   138  
   139  // TestHelloWorld_yamlAndSemiHardWired uses the MuxLookupKey to inject two lookup_key functions. The ConfigLookupKey
   140  // that consults the yaml config and the sayHello.
   141  func TestHelloWorld_yamlAndSemiHardWired(t *testing.T) {
   142  	configOptions := vf.Map(
   143  		provider.LookupKeyFunctions, []sdk.LookupKey{provider.ConfigLookupKey, sayHello},
   144  		api.HieraRoot, `testdata`)
   145  
   146  	// Initialize a Hiera session with the MuxLookupKey as the top-level function configured using the configOptions.
   147  	hiera.DoWithParent(context.Background(), provider.MuxLookupKey, configOptions, func(hs api.Session) {
   148  		// A lookup of just "hello" should hit the first provider, the ConfigLookupKey.
   149  		result := hiera.Lookup(hs.Invocation(nil, nil), `hello`, nil, nil)
   150  		if result == nil || `yaml data says hello` != result.String() {
   151  			t.Fatalf("unexpected result %v", result)
   152  		}
   153  
   154  		// A lookup of "howdy" is not found using the yaml configuration, so it hits the second provider, the sayHello.
   155  		result = hiera.Lookup(hs.Invocation(nil, nil), `howdy`, nil, nil)
   156  		if result == nil || `howdy world` != result.String() {
   157  			t.Fatalf("unexpected result %v", result)
   158  		}
   159  	})
   160  }