Movatterモバイル変換


[0]ホーム

URL:


CFEngine documentation homepage

vars

Suggest changes
Table of contents

Variables in CFEngine are definedas promises that an identifier of a certain type represents a particularvalue. Variables can be scalars or lists of typesstring,int,realordata.

The allowed characters in variable names are alphanumeric (both upper and lower case)and underscore.Associative arrays using the string type and square brackets[] toenclose an arbitrary key are being deprecated in favor of thedata variable type.

Scalar variables

string

Description: A scalar string

Type:string

Allowed input range: (arbitrary string)

Example:

code
vars:"xxx"string=>"Some literal string...";"yyy"string=>readfile("/home/mark/tmp/testfile","33");

int

Description: A scalar integer

Type:int

Allowed input range:-99999999999,99999999999

Example:

code
vars:"scalar"int=>"16k";"ran"int=>randomint(4,88);"dim_array"int=>readstringarray("array_name","/etc/passwd","#[^\n]*",":",10,4000);

Notes:

Int variables are strings that are expected to be used as integer numbers. Thetyping in CFEngine is dynamic, so the variable types are interchangeable.However, when you declare a variable to be typeint, CFEngine verifies thatthe value you assign to it looks like an integer (e.g., 3, -17, 16K).

real

Description: A scalar real number

Type:real

Allowed input range:-9.99999E100,9.99999E100

Example:

code
vars:"scalar"real=>"0.5";

Notes:

Real variables are strings that are expected to be used as real numbers. Thetyping in CFEngine is dynamic, so the variable types are interchangeable, butwhen you declare a variable to be typereal, CFEngine verifies that thevalue you assign to it looks like a real number (e.g., 3, 3.1415, .17,6.02e23, -9.21e-17).

Real numbers are not used in many places in CFEngine, but they are useful forrepresenting probabilities and performance data.

List variables

Lists are specified using curly brackets{} that enclose a comma-separatedlist of values. The order of the list is preserved by CFEngine.

slist

Description: A list of scalar strings

Type:slist

Allowed input range: (arbitrary string)

Example:

code
vars:"xxx"slist=>{"literal1","literal2"};"xxx1"slist=>{"1",@(xxx)};# interpolated in order"yyy"slist=>{readstringlist("/home/mark/tmp/testlist","#[a-zA-Z0-9 ]*","[^a-zA-Z0-9]",15,4000)};"zzz"slist=>{readstringlist("/home/mark/tmp/testlist2","#[^\n]*",",",5,4000)};

Notes:

Somefunctions returnslists, and anslistmay contain the values copied from anotherslist,rlist, orilist. Seepolicy.

ilist

Description: A list of integers

Type:ilist

Allowed input range:-99999999999,9999999999

Example:

code
vars:"variable_id"ilist=>{"10","11","12"};"xxx1"ilist=>{"1",@(variable_id)};# interpolated in order

Notes:

Integer lists are lists of strings that are expected to be treated asintegers. The typing in CFEngine is dynamic, so the variable types areinterchangeable, but when you declare a variable to be typeilist,CFEngine verifies that each value you assign to it looks like an integer(e.g., 3, -17, 16K).

Somefunctions returnilists, and anilist maycontain the values copied from anotherslist,rlist, orilist. Seepolicy

rlist

Description: A list of real numbers

Type:rlist

Allowed input range:-9.99999E100,9.99999E100

Example:

code
vars:"varid"rlist=>{"0.1","0.2","0.3"};"xxx1"rlist=>{"1.3",@(varid)};# interpolated in order

Notes:

Real lists are lists of strings that are expected to be used as realnumbers. The typing in CFEngine is dynamic, so the variable types areinterchangeable, but when you declare a variable to be typerlist,CFEngine verifies that each value you assign to it looks like a realnumber (e.g., 3, 3.1415, .17, 6.02e23, -9.21e-17).

Somefunctions returnrlists, and anrlist maycontain the values copied from anotherslist,rlist, orilist. Seepolicy

Data container variables

Thedata variables are obtained from functions that return datacontainers, such asreadjson(),readyaml(),parsejson(), orparseyaml(), the variousdata_* functions, or from mergingexisting data containers withmergedata(). They canNOT bemodified, once created.

Inline YAML and JSON data

Data containers can be specified inline, without calling functions.

Inline YAML data has to begin with the--- preamble followed by a newline. This preambleis normally optional but here (for inline YAML) it's required byCFEngine. To generate that in CFEngine, use$(const.n) or a literalnewline as shown in the example.

Inline JSON or YAML data may contain CFEngine variable references.They will be expanded at runtime as if they were simply calls toreadjson() orreadyaml(), which also means that syntax error inthe JSON or YAML data will only be caught when your policy is actuallybeing evaluated.

If the inline JSON or YAML data doesnot contain CFEngine variablereferences, it will be parsed at compile time, which means thatcf-promises will be able to find syntax errors in your JSON or YAMLdata early. Thus it is highly recommended that you try to avoidvariable references in your inline JSON or YAML data.

For example:

Inline Yaml example

code
bundleagentexample_inline_yaml{vars:# YAML requires "---" header (followed by newline)# NOTE \n is not interpreted as a newline, instead use $(const.n)"yaml_multi_line"data=>'----"CFEngine Champions":-Name:"Aleksey Tsalolikhin"Year:2011-Name:"Ted Zlatanov"Year:2013';"yaml_single_line"data=>'---$(const.n)-key1:value1$(const.n)-key2:value2';reports:"Data container defined from yaml_multi_line:$(with)"with=>storejson(@(yaml_multi_line));"Data container defined from yaml_single_line:$(with)"with=>storejson(@(yaml_single_line));}bundleagent__main__{methods:"example_inline_yaml";}
code
R: Data container defined from yaml_multi_line: [  {    "CFEngine Champions": [      {        "Name": "Aleksey Tsalolikhin",        "Year": 2011      },      {        "Name": "Ted Zlatanov",        "Year": 2013      }    ]  }]R: Data container defined from yaml_single_line: [  {    "key1": "value1"  },  {    "key2": "value2"  }]

This policy can be found in/var/cfengine/share/doc/examples/inline-yaml.cfand downloaded directly fromgithub.

Inline Json example

code
bundleagentexample_inline_json{vars:"json_multi_line"data=>'{"CFEngine Champions":[{"Name":"Aleksey Tsalolikhin","Year":"2011"},{"Name":"Ted Zlatanov","Year":"2013"}]}';"json_single_line"data=>'[{"key1":"value1"},{"key2":"value2"}]';reports:"Data container defined from json_multi_line:$(with)"with=>storejson(@(json_multi_line));"Data container defined from json_single_line:$(with)"with=>storejson(@(json_single_line));}bundleagent__main__{methods:"example_inline_json";}
code
R: Data container defined from json_multi_line: {    "CFEngine Champions": [      {        "Name": "Aleksey Tsalolikhin",        "Year": "2011"      },      {        "Name": "Ted Zlatanov",        "Year": "2013"      }    ]}R: Data container defined from json_single_line: [  {    "key1": "value1"  },  {    "key2": "value2"  }]

This policy can be found in/var/cfengine/share/doc/examples/inline-json.cfand downloaded directly fromgithub.

Passing data containers to bundles

Data containers can be passed to another bundle with the@(varname) notation, similarly to the list passing notation.

Some useful tips for using data containers

  • to extract justcontainer[x], usemergedata("container[x]")
  • to wrap a container in an array, usemergedata("[ container ]")
  • to wrap a container in a map, usemergedata('{ "mykey": container }')
  • they act like "classic" CFEngine arrays in many ways
  • getindices() andgetvalues() work on any level, e.g.getvalues("container[x][y]")
  • in reports, you have to reference a part of the container that can be expressed as a string. So for instance if you have the containerc with data{ "x": { "y": 50 }, "z": [ 1,2,3] } we have two top-level keys,x andz. If you report on$(c[x]) you will not get data, since there is no string there. But if you ask for$(c[x][y]) you'll get50, and if you ask for$(c[z]) you'll get implicit iteration on1,2,3 (just like a slist in a "classic" CFEngine array).
  • read the examples below carefully to see some useful ways to access data container contents

Iterating through a data container is only guaranteed to respect listorder (e.g.[1,3,20] will be iterated in that order). Key order formaps, as per the JSON standard, is not guaranteed. Similarly, callinggetindices() on a data container will give the list order of indices0, 1, 2, ... but will not give the keys of a map in any particularorder. Here's an example of iterating in list order:

code
bodycommoncontrol{bundlesequence=>{run};}bundleagentrun{vars:"x"data=>parsejson('[{"one":"a"},{"two":"b"},{"three":"c"}]');# get the numeric indices of x: 0, 1, 2"xi"slist=>getindices(x);# for each xi, make a variable xpiece_$(xi) so we'll have# xpiece_0, xpiece_1, xpiece_2. Each xpiece will have that# particular element of the list x."xpiece_$(xi)"string=>format("%S","x[$(xi)]");reports:"$(xi):$(xpiece_$(xi))";}

Output:

code
R: 0: {"one":"a"}R: 1: {"two":"b"}R: 2: {"three":"c"}

Often you need to iterate through the keys of a container, and thevalue is a key-value property map for that key. The example here showshow you can pass the "animals" container and an "animal" key inside itto a bundle, which can then report and use the data from the key-valueproperty map.

code
bodycommoncontrol{bundlesequence=>{run};}bundleagentrun{vars:"animals"data=>parsejson('{"dog":{"legs":4,"tail":true,"names":["Fido","Cooper","Sandy"]},"cat":{"legs":4,"tail":true,"names":["Fluffy","Snowball","Tabby"]},"dolphin":{"legs":0,"tail":true,"names":["Flipper","Duffy"]},"hamster":{"legs":4,"tail":true,"names":["Skullcrusher","Kimmy","Fluffadoo"]},}');"keys_unsorted"slist=>getindices("animals");"keys"slist=>sort(keys_unsorted,"lex");"animals_$(keys)"data=>mergedata("animals[$(keys)]");methods:# pass the container and a key inside it"any"usebundle=>analyze(@(animals),$(keys));}bundleagentanalyze(animals,a){vars:"names"slist=>getvalues("animals[$(a)][names]");"names_str"string=>format("%S",names);reports:"$(this.bundle): possible names for animal '$(a)':$(names_str)";"$(this.bundle): describe animal '$(a)' => name =$(a), legs =$(animals[$(a)][legs]), tail =$(animals[$(a)][tail])";}

Output:

code
R: analyze: possible names for animal 'cat': { "Fluffy", "Snowball", "Tabby" }R: analyze: describe animal 'cat' => name = cat, legs = 4, tail = trueR: analyze: possible names for animal 'dog': { "Fido", "Cooper", "Sandy" }R: analyze: describe animal 'dog' => name = dog, legs = 4, tail = trueR: analyze: possible names for animal 'dolphin': { "Flipper", "Duffy" }R: analyze: describe animal 'dolphin' => name = dolphin, legs = 0, tail = trueR: analyze: possible names for animal 'hamster': { "Skullcrusher", "Kimmy", "Fluffadoo" }R: analyze: describe animal 'hamster' => name = hamster, legs = 4, tail = true

data

Description: A data container structure

Type:data

Allowed input range: (arbitrary string)

Example:

code
vars:"loaded1"data=>readjson("/tmp/myfile.json",40000);"loaded2"data=>parsejson('{"key":"value"}');"loaded3"data=>readyaml("/tmp/myfile.yaml",40000);"loaded4"data=>parseyaml('-key2:value2');"merged1"data=>mergedata(loaded1,loaded2,loaded3,loaded4);# JSON or YAML can be inlined since CFEngine 3.7"inline1"data=>'{"key":"value"}';# JSON"inline2"data=>'---$(const.n)-key2:value2';# YAML requires "---$(const.n)" header

Attributes

policy

Description: The policy for (dis)allowing (re)definition of variables

Variables can either be allowed to change their value dynamically (beredefined) or they can be constant.

Type: (menu option)

Allowed input range:

code
freeoverridableconstantifdefined

Default value:

policy = free

Example:

code
vars:"varid"string=>"value...",policy=>"free";

Notes:

The policyfree andoverridable are synonyms. The policyconstant isdeprecated, and has no effect. All variables arefree oroverridable bydefault which means the variables values may be changed.

The policyifdefined applies only to lists and implies that unexpanded orundefined lists are dropped. The default behavior is otherwise to retain thisvalue as an indicator of the failure to quench the variable reference, forexample:

code
"one"slist=>{"1","2","3"};"list"slist=>{"@(one)",@(two)},policy=>"ifdefined";

This results in@(list) being the same as@(one), and the reference to@(two) disappears. This is useful for combining lists.

For example:

code
example_com::"domain"string=>"example.com",comment=>"Define a global domain for hosts in the example.com domain";# The promise above will be overridden by one of the ones below on hosts# within the matching subdomainone_example_com::"domain"string=>"one.example.com",comment=>"Define a global domain for hosts in the one.example.com domain";two_example_com::"domain"string=>"two.example.com",comment=>"Define a global domain for hosts in the two.example.com domain";

(Promises within the same bundle are evaluated top to bottom, so vars promises further down in a bundle can overwrite previous values of a variable. Seenormal ordering for more information).

Defining variables in foreign bundles

As a general rule, variables can only be defined or re-defined from within thebundle where they were defined. There are a few notable exceptions to thisgeneral rule which are described below.

Meta type promises

Variables defined by themeta promise type are defined in a bundle scope with the same name as the executing bundle suffixed withmeta.

Example policy:

code
bundleagentexample_meta_vars{meta:"tags"slist=>{"autorun"};vars:"myvar"string=>"my value";reports:"$(with)"with=>string_mustache("",variablesmatching_as_data(".*example_meta_vars.*"));}bundleagent__main__{methods:"example_meta_vars";}

Example output:

code
R: {  "default:example_meta_vars.myvar": "my value",  "default:example_meta_vars_meta.tags": [    "autorun"  ]}

Injecting variables into undefined bundles

Variables can be directly set in foreign bundles if the bundle is not defined.

Example policy:

code
bundleagentexample_variable_injection{vars:"undefined.myvar"string=>"my value";"cant_push_this.myvar"string=>"my value";reports:"$(with)"with=>string_mustache("",variablesmatching_as_data(".*myvar.*"));}bundleagentcant_push_this{# If a bundle is defined, you can't simply define a variable in it from# another bundle, unless the variable is defined via the module protocol.}bundleagent__main__{methods:"example_variable_injection";}

Example output:

code
   error: Ignoring remotely-injected variable 'myvar'   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Ignoring remotely-injected variable 'myvar'   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6R: {  "default:undefined.myvar": "my value"}   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6   error: Remote bundle variable injection detected!   error: Variable identifier 'cant_push_this.myvar' is not legal   error: Promise belongs to bundle 'example_variable_injection' in file '/tmp/example_variable_injection.cf' near line 6

Module protocol

The module protocol allows specification ofcontext (the bundle scope within which a variable gets defined).

Example policy:

code
bundleagentexample_variable_injection_via_module{commands:"/bin/echo '^context=undefined$(const.n)=myvar=my value"module=>"true";"/bin/echo '^context=cant_push_this$(const.n)=myvar=my value"module=>"true";reports:"$(with)"with=>string_mustache("",variablesmatching_as_data(".*myvar.*"));}bundleagentcant_push_this{# If a bundle is defined, you can't simply define a variable in it from# another bundle, unless the variable is defined via the module protocol.}bundleagent__main__{methods:"example_variable_injection_via_module";}

Example output:

code
R: {  "default:cant_push_this.myvar": "my value",  "default:undefined.myvar": "my value"}

Augments

Augments defines variables in thedef bundle scope.

This augments file that definesmy_var will be used for all examples shown here (/tmp/def.json).

code
{"vars":{"my_var":"My value defined from augments"}}

This example policy illustrates how augments defines variables in the def bundle scope (/tmp/example.cf).

code
bundlecommondef{vars:"some_var"string=>"My value for$(this.promiser) defined in Policy";}bundleagent__main__{reports:"$(with)"with=>string_mustache("",variablesmatching_as_data("default:def.*"));}

This command shows the execution and output from the policy above.

code
cf-agent -Kf /tmp/example.cf
code
R: {  "default:def.jq": "jq --compact-output --monochrome-output --ascii-output --unbuffered --sort-keys",  "default:def.my_var": "My value defined from augments",  "default:def.some_var": "My value for some_var defined in Policy"}

Note, augments defines the variables at the start of agent initialization. The variables can be re-defined by policy during evaluation.

This example policy illustrates how policy will, by default, re-define variables set via augments (/tmp/example2.cf).

code
bundlecommondef{vars:"some_var"string=>"My value for$(this.promiser) defined in Policy";"my_var"string=>"My value for$(this.promiser) defined in Policy";}bundleagent__main__{reports:"$(with)"with=>string_mustache("",variablesmatching_as_data("default:def.*"));}

This command shows the execution and output from the policy above.

code
cf-agent -Kf /tmp/example2.cf
code
R: {  "default:def.jq": "jq --compact-output --monochrome-output --ascii-output --unbuffered --sort-keys",  "default:def.my_var": "My value for my_var defined in Policy",  "default:def.some_var": "My value for some_var defined in Policy"}

Thus augments can be used to override defaults if the policy is instrumented to support it.

This example policy illustrates how policy can be instrumented to avoid re-definition of variables set via augments (/tmp/example3.cf).

code
bundlecommondef{vars:"some_var"string=>"My value for$(this.promiser) defined in Policy";# Here we set my_var if it has not yet been defined (as in the case where# augments would define it before the policy was evaluated)."my_var"string=>"My value for$(this.promiser) defined in Policy",unless=>isvariable($(this.promiser));}bundleagent__main__{reports:"$(with)"with=>string_mustache("",variablesmatching_as_data("default:def.*"));}

This command shows the execution and output from the policy above.

code
cf-agent -Kf /tmp/example3.cf
code
R: {  "default:def.jq": "jq --compact-output --monochrome-output --ascii-output --unbuffered --sort-keys",  "default:def.my_var": "My value defined from augments",  "default:def.some_var": "My value for some_var defined in Policy"}

Still need help?

Chat Ask a question on Github Mailing list
Version 
master3.24 (LTS)3.21 (LTS)view all versions

[8]ページ先頭

©2009-2025 Movatter.jp