blob: ffcc19f6e4684c54151ee5f4ae876db4e3b83331 [file] [log] [blame]
garciadeblas83775ba2025-07-23 18:35:24 +02001#######################################################################################
2# Copyright ETSI Contributors and Others.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13# implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#######################################################################################
17
18# Module with custom functions to manage KSUs and their renderization of the corresponding ResourceList into a given target folder.
19
20
21use ../krm *
22use ./location.nu
23use ./pattern.nu
24
25
26# Render a KSU, based on a KSU instance model received from stdin.
27export def create [
28 --dry-run # If set, only prints the generated ResourceList(s) along with the target folder(s) (i.e., it does not write to any folder)
29 --print-target-folder # If set, prints the target folder. Requires --dry-run
30 environment: record = {} # Record with environment variables to load
31]: [
32 record -> record
33 record -> nothing
34] {
35 # Get KSU structure
36 let in_ksu: record = $in
37
38 # Get the KSU name
39 let ksu_name: string = ($in_ksu | get "name")
40
41 # Add to the environment a key with the KSU name, so that it can be replaced
42 let updated_environment: record = (
43 $environment
44 | upsert $.KSU_NAME $ksu_name
45 )
46
47 # Update the KSU record accordingly
48 let updated_ksu: record = (
49 $in_ksu
50 | replace vars $updated_environment
51 )
52
53 # Get the rest of key parts
54 let sync: bool = ($updated_ksu | get -i "sync" | default false)
55 let target: string = (
56 $updated_ksu
57 | get "target"
58 | location to absolute path
59 )
60 let patterns: list<record> = ($updated_ksu | get "patterns")
61
62 # Process all the patterns and create a list of ResourceLists using the updated environment
63 $patterns
64 | each {|pat|
65 $pat
66 | pattern create $updated_environment
67 }
68 # Merge all the ResourceLists
69 | reduce {|elt, acc|
70 $acc
71 | concatenate resourcelists $elt
72 }
73 # Render
74 | if $dry_run {
75 if $print_target_folder { print $"TARGET FOLDER: ($target)" }
76 $in
77 } else {
78 $in
79 | convert resourcelist to folder --sync=$sync $target
80 }
81}
82
83
84# Delete a KSU, based on a KSU instance model received from stdin.
85export def delete [
86 --dry-run # If set, only prints the ResourceList(s) that would be removed (i.e., it does not write to any folder).
87 --print-target-folder # If set, prints the target folder and the list of files to be delete delete. Requires --dry-run.
88 environment: record = {} # Record with environment variables to load.
89]: [
90 record -> record
91 record -> nothing
92] {
93 # Get KSU structure
94 let in_ksu: record = $in
95
96 # Get the KSU name
97 let ksu_name: string = ($in_ksu | get "name")
98
99 # Add to the environment a key with the KSU name, so that it can be replaced
100 let updated_environment: record = (
101 $environment
102 | upsert $.KSU_NAME $ksu_name
103 )
104
105 # Update the KSU record accordingly
106 let updated_ksu: record = (
107 $in_ksu
108 | replace vars $updated_environment
109 )
110
111 # Get the rest of key parts
112 let target: string = (
113 $updated_ksu
114 | get "target"
115 | location to absolute path
116 )
117
118 # Delete
119 | if $dry_run {
120 if $print_target_folder {
121 print $"TARGET FOLDER: ($target)"
122 (ls ($"($target)/**/*" | into glob ) | table -e | print)
123 }
124 # Returns the ResourceList that would be deleted
125 {} | convert folder to resourcelist $target
126 } else {
127 rm -rf $target
128 }
129}
130
131
132# Update a KSU, based on a KSU instance model received from stdin.
133export def update [
134 --dry-run # If set, only prints the ResourceList(s) that would be re-generated (i.e., it does not write to any folder).
135 --print-target-folder # If set, print the target folder(s) to be updated. Requires --dry-run.
136 --diff-files # If set, lists the expected diff with respect to the existing folder(s). Requires --dry-run.
137 --diff # If set, prints the expected diff with respect to the existing folder(s). Requires --dry-run. It can be combined with `--diff-files`.
138 environment: record = {} # Record with environment variables to load.
139]: [
140 record -> record
141 record -> string
142 record -> nothing
143] {
144 # Get KSU structure
145 let in_ksu: record = $in
146
147 # If it is not a dry-run, we simply need to re-create the KSU and return
148 if not $dry_run {
149 ## Note that the raw input variables are used, since the full environment pre-processing already happens in both custom commands
150 $in_ksu | delete $environment
151 $in_ksu | create $environment
152
153 return
154 }
155 # ... otherwise, all the dry-run calculations will need to be performed
156
157 # Get the KSU name
158 let ksu_name: string = ($in_ksu | get "name")
159
160 # Calculate the original target folder
161 let target: string = (
162 $in_ksu
163 | replace vars ($environment | upsert $.KSU_NAME $ksu_name)
164 | get "target"
165 | location to absolute path
166 )
167
168 # Generate the resource contents of the planned update in a temporary fleet repos base
169 let tmp_fleet_repos_base: path = (mktemp -t -d)
170
171 let tmp_environment: record = (
172 $environment
173 | upsert $.FLEET_REPOS_BASE $tmp_fleet_repos_base
174 )
175
176 let tmp_target: string = (
177 $in_ksu
178 | replace vars ($tmp_environment | upsert $.KSU_NAME $ksu_name)
179 | get "target"
180 | location to absolute path
181 )
182
183 # Render the desired manifests into a temporary location
184 $in_ksu | create $tmp_environment
185
186 # If specified, prints the target folder
187 if $print_target_folder {
188 print $"TARGET FOLDER: ($target)\n"
189 }
190
191 # If specified, prints all the differences with respect to the original folder
192 if ($diff_files or $diff) {
193 let differences: string = (
194 []
195 # Add list of different files, if needed
196 | if $diff_files {
197 $in
198 | append (
199 ^diff -rqN $target $tmp_target
200 # Prevent the diff error code, due to potential file differences, ends up breaking the full pipeline
201 | complete | get stdout
202 )
203 # Add detail of differences, if needed
204 } else { $in }
205 | if $diff {
206 $in
207 | append (
208 ^diff -rN $target $tmp_target
209 # Prevent the diff error code, due to potential file differences, ends up breaking the full pipeline
210 | complete | get stdout
211 )
212 } else { $in }
213 | str join "\n\n"
214 )
215
216 # Remove the temporary fleet repos base folder
217 rm -rf $tmp_fleet_repos_base
218
219 # Return the differences found by diff
220 $differences
221
222 # Otherwise, just returns the planned ResourceList
223 } else {
224 # Converts the planned resources to a ResourceList
225 let output_rl: record = ( {} | convert folder to resourcelist $tmp_target )
226
227 # Remove the temporary fleet repos base folder
228 rm -rf $tmp_fleet_repos_base
229
230 # Finally, returns the calculated ResourceList
231 $output_rl
232 }
233}