Re: Re: Modify a YAML file

"'Nick Anderson' via help-cfengine" <[email protected]> Wed, 13 Aug 2025 09:42:22 -0500
Newsgroups gmane.comp.sysutils.cfengine.general
Message-ID <[email protected]>
--=-=-=
Content-Type: multipart/alternative; boundary="==-=-="

--==-=-=
Content-Type: text/plain; charset="UTF-8"

IN_PROGRESS Respond to 'Lars Erik Wik' via help-cfengine <[email protected]>: Re: [help-cfengine] Re: Modify a YAML file :email:CFEngine:support:
=====================================================================================================================================

  Here is another variant that uses a data structure (here it's a
  classic associative array, but it could be a data container (defined
  from JSON or YAML etc ...)

  ,----
  | bundle agent __main__
  | {
  |   methods:
  |       "init";
  |       "test";
  |       "check";
  | }
  |
  | bundle agent init
  | {
  |   # Create a file with original content
  |   files:
  |     "/tmp/somefile.yaml"
  |       content => "ipaddr: 10.0.0.1
  | network: 10.0.0.0";
  | }
  |
  | bundle agent test
  | {
  |   # Replace IP address of file
  |   vars:
  |       "start_ends[ipaddr]" string => "172.16.1.1";
  |       "start_ends[network]" string => "172.16.1.0";
  |       "l_start_ends" slist => getindices( start_ends );
  |
  |   files:
  |
  |       # As others say, full file management is ideal, if you can do that
  |       #
  |       # This shows one way to leverage variables to call this multiple times
  |       # BUT, this is still not ideal, because you are potentially causing an edit for each iteration.
  |       # It's better to do all the edits in one operation, in which case you would need to pass the full map to the edit_line bundle.
  |       # You may need to construct your own edit_line bundel to do exsactly what you need
  |       # Look at other edit_line bundles in the stdlib that contain replace_lines:
  |
  |     "/tmp/somefile.yaml"
  |       edit_line => replace_line_end("$(l_start_ends):", "$(start_ends[$(l_start_ends)])" );
  | }
  |
  | bundle agent check
  | {
  |   # Check if file has correct content after edit
  |   classes:
  |     "ok"
  |       expression => strcmp(readfile("/tmp/somefile.yaml"), "ipaddr: 172.16.1.1
  | network: 172.16.1.0
  | "),
  |       if => fileexists("/tmp/somefile.yaml");
  |
  |   # Print message based on outcome
  |   reports:
  |     ok::
  |       "IP addr was replaced";
  |     !ok::
  |       "IP addr was not replaced";
  | }
  `----

  ,----
  |     info: Created file '/tmp/somefile.yaml', mode 0600
  |     info: Updated file '/tmp/somefile.yaml' with content 'ipaddr: 10.0.0.1
  | network: 10.0.0.0'
  |     info: Set field sub-value '172.16.1.0' in '/tmp/somefile.yaml'
  |     info: fields_edit promise '\s*network:\s.*' repaired
  |     info: Edited file '/tmp/somefile.yaml'
  |     info: Set field sub-value '172.16.1.1' in '/tmp/somefile.yaml'
  |     info: fields_edit promise '\s*ipaddr:\s.*' repaired
  |     info: Edited file '/tmp/somefile.yaml'
  | R: IP addr was replaced
  `----

-- 
You received this message because you are subscribed to the Google Groups "help-cfengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/help-cfengine/87ikirp9jx.fsf%40northern.tech.

--==-=-=
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<p>
Here is another variant that uses a data structure (here it's a classic ass=
ociative array, but it could be a data container (defined from JSON or YAML=
 etc &#x2026;)
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-cfengine3"><span style=3D"color: #a89984; font-weight=
: bold;">bundle</span> <span style=3D"color: #458588; font-weight: bold;">a=
gent</span> <span style=3D"color: #458588;">__main__</span>
<span style=3D"color: #689d6a;">{</span>
  <span style=3D"color: #a89984; font-weight: bold;">methods</span>:
      <span style=3D"color: #689d6a;">"init"</span>;
      <span style=3D"color: #689d6a;">"test"</span>;
      <span style=3D"color: #689d6a;">"check"</span>;
<span style=3D"color: #689d6a;">}</span>

<span style=3D"color: #a89984; font-weight: bold;">bundle</span> <span styl=
e=3D"color: #458588; font-weight: bold;">agent</span> <span style=3D"color:=
 #458588;">init</span>
<span style=3D"color: #689d6a;">{</span>
  <span style=3D"color: #7c6f64;"># Create a file with original content
</span>  <span style=3D"color: #a89984; font-weight: bold;">files</span>:
    <span style=3D"color: #689d6a;">"/tmp/somefile.yaml"</span>
      content =3D&gt; <span style=3D"color: #689d6a;">"ipaddr: 10.0.0.1
network: 10.0.0.0"</span>;
<span style=3D"color: #689d6a;">}</span>

<span style=3D"color: #a89984; font-weight: bold;">bundle</span> <span styl=
e=3D"color: #458588; font-weight: bold;">agent</span> <span style=3D"color:=
 #458588;">test</span>
<span style=3D"color: #689d6a;">{</span>
  <span style=3D"color: #7c6f64;"># Replace IP address of file
</span>  <span style=3D"color: #a89984; font-weight: bold;">vars</span>:
      <span style=3D"color: #689d6a;">"start_ends[ipaddr]"</span> <span sty=
le=3D"color: #d79921;">string</span> =3D&gt; <span style=3D"color: #689d6a;=
">"172.16.1.1"</span>;
      <span style=3D"color: #689d6a;">"start_ends[network]"</span> <span st=
yle=3D"color: #d79921;">string</span> =3D&gt; <span style=3D"color: #689d6a=
;">"172.16.1.0"</span>;
      <span style=3D"color: #689d6a;">"l_start_ends"</span> <span style=3D"=
color: #d79921;">slist</span> =3D&gt; getindices<span style=3D"color: #d799=
21;">(</span> start_ends <span style=3D"color: #d79921;">)</span>;

  <span style=3D"color: #a89984; font-weight: bold;">files</span>:

      <span style=3D"color: #7c6f64;"># As others say, full file management=
 is ideal, if you can do that
</span>      <span style=3D"color: #7c6f64;">#
</span>      <span style=3D"color: #7c6f64;"># This shows one way to levera=
ge variables to call this multiple times
</span>      <span style=3D"color: #7c6f64;"># BUT, this is still not ideal=
, because you are potentially causing an edit for each iteration.
</span>      <span style=3D"color: #7c6f64;"># It's better to do all the ed=
its in one operation, in which case you would need to pass the full map to =
the edit_line bundle.
</span>      <span style=3D"color: #7c6f64;"># You may need to construct yo=
ur own edit_line bundel to do exsactly what you need
</span>      <span style=3D"color: #7c6f64;"># Look at other edit_line bund=
les in the stdlib that contain replace_lines:
</span>
    <span style=3D"color: #689d6a;">"/tmp/somefile.yaml"</span>
      edit_line =3D&gt; replace_line_end<span style=3D"color: #d79921;">(</=
span><span style=3D"color: #689d6a;">"$(l_start_ends):"</span>, <span style=
=3D"color: #689d6a;">"$(start_ends[$(l_start_ends)])"</span> <span style=3D=
"color: #d79921;">)</span>;
<span style=3D"color: #689d6a;">}</span>

<span style=3D"color: #a89984; font-weight: bold;">bundle</span> <span styl=
e=3D"color: #458588; font-weight: bold;">agent</span> <span style=3D"color:=
 #458588;">check</span>
<span style=3D"color: #689d6a;">{</span>
  <span style=3D"color: #7c6f64;"># Check if file has correct content after=
 edit
</span>  <span style=3D"color: #a89984; font-weight: bold;">classes</span>:
    <span style=3D"color: #689d6a;">"ok"</span>
      expression =3D&gt; strcmp<span style=3D"color: #d79921;">(</span>read=
file<span style=3D"color: #458588;">(</span><span style=3D"color: #689d6a;"=
>"/tmp/somefile.yaml"</span><span style=3D"color: #458588;">)</span>, <span=
 style=3D"color: #689d6a;">"ipaddr: 172.16.1.1
network: 172.16.1.0
"</span><span style=3D"color: #d79921;">)</span>,
      if =3D&gt; fileexists<span style=3D"color: #d79921;">(</span><span st=
yle=3D"color: #689d6a;">"/tmp/somefile.yaml"</span><span style=3D"color: #d=
79921;">)</span>;

  <span style=3D"color: #7c6f64;"># Print message based on outcome
</span>  <span style=3D"color: #a89984; font-weight: bold;">reports</span>:
    <span style=3D"color: #98971a; font-weight: bold;">ok</span>::
      <span style=3D"color: #689d6a;">"IP addr was replaced"</span>;
    <span style=3D"color: #98971a; font-weight: bold;">!ok</span>::
      <span style=3D"color: #689d6a;">"IP addr was not replaced"</span>;
<span style=3D"color: #689d6a;">}</span>
</pre>
</div>

<pre class=3D"example" id=3D"org2c2f6b2">
    info: Created file '/tmp/somefile.yaml', mode 0600
    info: Updated file '/tmp/somefile.yaml' with content 'ipaddr: 10.0.0.1
network: 10.0.0.0'
    info: Set field sub-value '172.16.1.0' in '/tmp/somefile.yaml'
    info: fields_edit promise '\s*network:\s.*' repaired
    info: Edited file '/tmp/somefile.yaml'
    info: Set field sub-value '172.16.1.1' in '/tmp/somefile.yaml'
    info: fields_edit promise '\s*ipaddr:\s.*' repaired
    info: Edited file '/tmp/somefile.yaml'
R: IP addr was replaced
</pre>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;help-cfengine&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]">help-=
[email protected]</a>.<br />
To view this discussion visit <a href=3D"https://groups.google.com/d/msgid/=
help-cfengine/87ikirp9jx.fsf%40northern.tech?utm_medium=3Demail&utm_source=
=3Dfooter">https://groups.google.com/d/msgid/help-cfengine/87ikirp9jx.fsf%4=
0northern.tech</a>.<br />

--==-=-=--

--=-=-=
Content-Type: text/plain; charset="UTF-8"




--
Nick Anderson | Doer of Things | (+1) 785-550-1767 | https://northern.tech

-- 
You received this message because you are subscribed to the Google Groups "help-cfengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/help-cfengine/87ikirp9jx.fsf%40northern.tech.

--=-=-=--