1 #######################################################################################
2 # Copyright ETSI Contributors and Others.
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #######################################################################################
18 # ===========================================================================================
19 # OSM Application Management Workflow Template
20 # ===========================================================================================
23 # - PVC containing application model and parameters must exist
24 # - Required files: app_instance_model.yaml, parameters/clear/environment.yaml, parameters/secret/environment.yaml
25 # - Git repositories for Fleet and SW-Catalogs must be accessible
28 # Use the launcher workflows (launcher-app.yaml) or create custom workflows that reference
29 # this template. Ensure the model_volume_name parameter points to a properly prepared PVC.
31 # For volume preparation utilities, see: scripts/library/osm/utils/workflow-pvc
33 # ===========================================================================================
35 apiVersion: argoproj.io/v1alpha1
36 kind: WorkflowTemplate
38 name: full-app-management-wft
39 namespace: osm-workflows
43 # === Core Operation Configuration ===
46 Full command string to execute with the OSM SDK.
48 - "app create $environment": Deploy new application instance
49 - "app update $environment": Update existing application instance
50 - "app delete $environment": Remove application instance
51 This parameter accepts any valid OSM SDK command for maximum flexibility.
53 # === Volume-Based Data Sources ===
54 - name: model_volume_name
56 Name of the PersistentVolumeClaim containing application models and parameters.
57 The PVC must contain the following structure:
58 - /app_instance_model.yaml: Application instantiation model (required)
59 - /parameters/clear/environment.yaml: Clear text parameters (optional)
60 Secret parameters are mounted separately via the secret_name parameter.
63 Name of the Kubernetes secret to mount at /model/parameters/secret/environment.yaml.
64 This parameter is optional. When provided, the secret will be mounted as a file
65 containing sensitive configuration parameters for the application.
67 # === Git Repository Configuration ===
69 - name: fleet_destination_folder
70 value: "/fleet/fleet-osm"
71 - name: git_fleet_cred_secret
72 - name: git_sw_catalogs_url
73 - name: sw_catalogs_destination_folder
74 value: "/sw-catalogs/sw-catalogs-osm"
75 - name: git_sw_catalogs_cred_secret
77 # === Target Deployment Configuration ===
85 # === OSM SDK Container Configuration ===
86 - name: osm_sdk_image_repository
87 value: "opensourcemano/osm-nushell-krm-functions"
89 Repository for the OSM SDK container image. Default is the standardized
90 OSM SDK operations image that provides consistent behavior across workflows.
91 - name: osm_sdk_image_tag
92 value: "testing-daily"
94 Tag for the OSM SDK container image. Default is '24h' which provides
95 a stable, time-limited image for workflow execution.
97 # === Workflow Execution Control ===
101 Enable debug mode for detailed workflow execution information.
102 When set to 'true', additional debug steps will execute to provide:
103 - Volume mount status and accessibility checks
104 - Model content analysis and validation
105 - Repository structure inspection
106 - Embedded operations testing
107 Set to 'true' for troubleshooting workflow issues.
111 Enable dry-run mode to validate operations without making changes.
112 When set to 'true', the workflow will:
113 - Perform all validation and preparation steps
114 - Execute app operations in dry-run mode (no actual changes)
115 - Skip Git commit and push operations
116 Use this mode to test workflow configuration and validate models.
118 # === Workflow Lifecycle Management ===
119 # TTL strategy for automatic cleanup of completed workflow instances
121 secondsAfterCompletion: 6000 # 100 minutes - Time to live after workflow completion
122 secondsAfterSuccess: 6000 # 100 minutes - Time to live after successful execution
123 secondsAfterFailure: 9000 # 150 minutes - Extended time for failure analysis
125 # Main entry point for the workflow template
126 entrypoint: app-management
129 # === Main Application Management Template ===
130 # This template orchestrates the complete application lifecycle management process
131 # using a volume-based approach for application models and parameters.
132 - name: app-management
135 # Core operation configuration
137 # Volume-based data sources
138 - name: model_volume_name
140 # Git repository configuration for Fleet and SW-Catalogs
141 - name: git_fleet_url
142 - name: fleet_destination_folder
143 - name: git_fleet_cred_secret
144 - name: git_sw_catalogs_url
145 - name: sw_catalogs_destination_folder
146 - name: git_sw_catalogs_cred_secret
147 # Target deployment configuration
152 # OSM SDK container configuration with standardized defaults
153 - name: osm_sdk_image_repository
154 - name: osm_sdk_image_tag
155 # Workflow execution control flags
160 # === PHASE 1: Parameter Validation ===
161 # Validate that all required parameters are provided for volume-based workflow execution
162 - - name: validate-parameters
170 echo "=== Volume-Based Workflow Parameter Validation ==="
171 echo "Validating required parameters for application management..."
173 # Validate core volume parameter
174 if [ -z "{{inputs.parameters.model_volume_name}}" ]; then
175 echo "ERROR: model_volume_name parameter is required for volume-based workflow"
176 echo "Please provide a PVC name containing the application model and parameters"
180 # Validate Git repository parameters
181 if [ -z "{{inputs.parameters.git_fleet_url}}" ]; then
182 echo "ERROR: git_fleet_url parameter is required for Fleet repository access"
186 if [ -z "{{inputs.parameters.git_sw_catalogs_url}}" ]; then
187 echo "ERROR: git_sw_catalogs_url parameter is required for SW-Catalogs repository access"
191 # Validate target deployment parameters
192 if [ -z "{{inputs.parameters.app_name}}" ]; then
193 echo "ERROR: app_name parameter is required for application identification"
197 if [ -z "{{inputs.parameters.profile_name}}" ]; then
198 echo "ERROR: profile_name parameter is required for deployment profile"
202 echo "✓ All required parameters validated successfully"
203 echo "Configuration Summary:"
204 echo " Command: {{inputs.parameters.command}}"
205 echo " Model Volume: {{inputs.parameters.model_volume_name}}"
206 echo " Secret Name: {{inputs.parameters.secret_name}}"
207 echo " Application: {{inputs.parameters.app_name}}"
208 echo " Profile: {{inputs.parameters.profile_name}} ({{inputs.parameters.profile_type}})"
209 echo " Project: {{inputs.parameters.project_name}}"
210 echo " OSM SDK: {{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
211 echo " Debug Mode: {{inputs.parameters.debug}}"
212 echo " Dry Run: {{inputs.parameters.dry_run}}"
214 # === PHASE 2: Volume Preparation ===
215 # Generate temporary volumes for Git repository operations
216 # These volumes will store cloned Fleet and SW-Catalogs repositories during workflow execution
217 - - name: generate-fleet-volume-repo
219 name: k8s-resources-wft
220 template: generate-volume
224 value: '100Mi' # Sufficient space for Fleet repository content
225 - name: generate-sw-catalogs-volume-repo
227 name: k8s-resources-wft
228 template: generate-volume
232 value: '100Mi' # Sufficient space for SW-Catalogs repository content
234 # === PHASE 3: Git Repository Cloning ===
235 # Clone the required Git repositories for application modeling and deployment
236 # These repositories provide the templates and target locations for GitOps operations
237 - - name: clone-fleet
246 value: "{{inputs.parameters.git_fleet_url}}"
247 - name: destination_folder
248 value: "{{inputs.parameters.fleet_destination_folder}}"
249 - name: git_cred_secret
250 value: "{{inputs.parameters.git_fleet_cred_secret}}"
251 - name: git_volume_name
252 value: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
253 - name: clone-sw-catalogs
260 value: "/sw-catalogs"
262 value: "{{inputs.parameters.git_sw_catalogs_url}}"
263 - name: destination_folder
264 value: "{{inputs.parameters.sw_catalogs_destination_folder}}"
265 - name: git_cred_secret
266 value: "{{inputs.parameters.git_sw_catalogs_cred_secret}}"
267 - name: git_volume_name
268 value: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
270 # === PHASE 4: Debug Information (Optional) ===
271 # Comprehensive debugging information for volume-based workflow troubleshooting
272 # Executed only when debug parameter is set to true
274 when: "{{inputs.parameters.debug}} == true"
277 image: "{{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
282 print "=== OSM App Modeling Debug Information (Volume-Based) ==="
283 print $"Command: {{inputs.parameters.command}}"
284 print $"SDK Image: {{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
285 print $"Model Volume: {{inputs.parameters.model_volume_name}}"
286 print $"Secret Name: {{inputs.parameters.secret_name}}"
287 print $"Timestamp: (date now | format date '%Y-%m-%d %H:%M:%S')"
290 print "=== Volume Mount Status and Accessibility ==="
291 print "Checking volume mount accessibility..."
293 # Check model volume mount
294 print "Model volume mount status:"
295 if (ls /model | length) > 0 {
296 print "✓ Model volume mounted successfully at /model"
297 print $" Files found: (ls /model | length)"
299 print "✗ Model volume mount failed or empty"
302 # Check fleet volume mount
303 print "Fleet volume mount status:"
304 if (ls /repos/fleet-osm | length) > 0 {
305 print "✓ Fleet volume mounted successfully at /repos/fleet-osm"
306 print $" Files found: (ls /repos/fleet-osm | length)"
308 print "✗ Fleet volume mount failed or empty"
311 # Check sw-catalogs volume mount
312 print "SW-Catalogs volume mount status:"
313 if (ls /repos/sw-catalogs-osm | length) > 0 {
314 print "✓ SW-Catalogs volume mounted successfully at /repos/sw-catalogs-osm"
315 print $" Files found: (ls /repos/sw-catalogs-osm | length)"
317 print "✗ SW-Catalogs volume mount failed or empty"
321 print "=== Model Volume Contents and Structure ==="
322 print "Model volume directory structure:"
324 ls /model -la | select name type size mode | table
326 print "Error accessing model volume contents"
330 print "=== Required Model Files Validation ==="
331 # Check app_instance_model.yaml
332 if ("/model/app_instance_model.yaml" | path exists) {
333 print "✓ app_instance_model.yaml found"
335 let file_size = (ls /model/app_instance_model.yaml | get size | first)
336 print $" Size: ($file_size) bytes"
338 print " Warning: Could not read file size"
341 print "✗ app_instance_model.yaml missing"
344 # Check clear parameters
345 if ("/model/parameters/clear/environment.yaml" | path exists) {
346 print "✓ Clear parameters file found"
348 let file_size = (ls /model/parameters/clear/environment.yaml | get size | first)
349 print $" Size: ($file_size) bytes"
351 print " Warning: Could not read file size"
354 print "ℹ Clear parameters file missing (optional)"
357 # Check secret parameters
358 if ("/model/parameters/secret/environment.yaml" | path exists) {
359 print "✓ Secret parameters file found"
361 let file_size = (ls /model/parameters/secret/environment.yaml | get size | first)
362 print $" Size: ($file_size) bytes"
364 print " Warning: Could not read file size"
367 print "ℹ Secret parameters file missing (optional)"
370 print "Clear Parameters Content:"
372 let clear_params = open /model/parameters/clear/environment.yaml | to yaml
375 print "Clear parameters not available"
379 print "Secret Parameters Content (masked for security):"
381 if ("/model/parameters/secret/environment.yaml" | path exists) {
382 print "Secret file exists - content masked for security"
384 print "Secret parameters not available"
387 print "Error checking secret parameters"
391 print "=== Loaded Model Instance from Volume ==="
393 $model_instance | to yaml
394 print $model_instance
396 print "Error loading model instance"
400 print "=== Environment Parameters from Volume ==="
402 $environment | to yaml
405 print "Error loading environment"
409 print "=== Repository Structure ==="
410 print "Fleet repo contents:"
412 ls /repos/fleet-osm | select name type size | first 10 | table
414 print "Error accessing fleet repository"
417 print "SW-Catalogs repo contents:"
419 ls /repos/sw-catalogs-osm | select name type size | first 10 | table
421 print "Error accessing sw-catalogs repository"
425 print "=== Embedded Operations Validation ==="
426 print "App Operations Library Status:"
428 help app | lines | first 10 | str join "\n"
430 print "Error accessing app operations library"
434 print "=== Dry Run Test ==="
435 print "Testing command execution with volume-mounted data..."
437 print $"Command to execute: {{inputs.parameters.command}}"
438 print "✓ Command validation successful with volume-based data"
440 print $"✗ Command validation failed: ($in)"
444 print "=== Debug Information Complete ==="
449 mountPath: /repos/fleet-osm
451 - name: sw-catalogs-volume
452 mountPath: /repos/sw-catalogs-osm
453 subPath: sw-catalogs-osm
454 # Mount secret volume when secret_name is provided
455 - name: secret-volume
456 mountPath: /model/parameters/secret
460 persistentVolumeClaim:
461 claimName: "{{inputs.parameters.model_volume_name}}"
463 persistentVolumeClaim:
464 claimName: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
465 - name: sw-catalogs-volume
466 persistentVolumeClaim:
467 claimName: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
468 - name: secret-volume
470 secretName: "{{inputs.parameters.secret_name}}"
473 # === PHASE 5: Application Operations ===
474 # This phase performs the actual create/update/delete operations on the application model
475 - - name: run-app-operation
476 when: "{{inputs.parameters.dry_run}} != true"
479 image: "{{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
480 args: ["{{inputs.parameters.command}}"] # Full command string to execute
482 # Mount model volume containing application data
485 # Mount Fleet repository for GitOps target
487 mountPath: /repos/fleet-osm
489 # Mount SW-Catalogs repository for application templates
490 - name: sw-catalogs-volume
491 mountPath: /repos/sw-catalogs-osm
492 subPath: sw-catalogs-osm
493 # Mount secret volume when secret_name is provided
494 - name: secret-volume
495 mountPath: /model/parameters/secret
499 persistentVolumeClaim:
500 claimName: "{{inputs.parameters.model_volume_name}}"
502 persistentVolumeClaim:
503 claimName: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
504 - name: sw-catalogs-volume
505 persistentVolumeClaim:
506 claimName: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
507 - name: secret-volume
509 secretName: "{{inputs.parameters.secret_name}}"
511 # Dry-run variant of the app operation for validation without changes
512 - name: run-app-operation-dry-run
513 when: "{{inputs.parameters.dry_run}} == true"
516 image: "{{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
517 args: ["{{inputs.parameters.command}} --dry-run"] # Full command string with dry-run flag
519 # Same volume mounts as regular operation for consistency
523 mountPath: /repos/fleet-osm
525 - name: sw-catalogs-volume
526 mountPath: /repos/sw-catalogs-osm
527 subPath: sw-catalogs-osm
528 # Mount secret volume when secret_name is provided
529 - name: secret-volume
530 mountPath: /model/parameters/secret
534 persistentVolumeClaim:
535 claimName: "{{inputs.parameters.model_volume_name}}"
537 persistentVolumeClaim:
538 claimName: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
539 - name: sw-catalogs-volume
540 persistentVolumeClaim:
541 claimName: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
542 - name: secret-volume
544 secretName: "{{inputs.parameters.secret_name}}"
547 # === PHASE 7: GitOps Commit and Push ===
548 # Commit and push the generated application manifests to the Fleet repository
549 # This completes the GitOps workflow by updating the target repository with changes
550 - - name: push-to-fleet
553 template: git-commit-merge-push
559 value: "{{inputs.parameters.fleet_destination_folder}}"
560 - name: git_cred_secret
561 value: "{{inputs.parameters.git_fleet_cred_secret}}"
562 - name: git_volume_name
563 value: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
564 - name: commit_message
565 value: "Execute '{{inputs.parameters.command}}' for App '{{inputs.parameters.app_name}}' in {{inputs.parameters.profile_name}} profile ({{inputs.parameters.profile_type}}) @ {{inputs.parameters.project_name}} project [Volume-Based Workflow]"
568 - name: contrib_branch
571 value: "{{inputs.parameters.dry_run}}"