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: "ttl.sh/osm-sdk-operations"
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
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 echo "=== OSM App Modeling Debug Information (Volume-Based) ==="
283 echo $"Command: {{inputs.parameters.command}}"
284 echo $"SDK Image: {{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
285 echo $"Model Volume: {{inputs.parameters.model_volume_name}}"
286 echo $"Secret Name: {{inputs.parameters.secret_name}}"
287 echo $"Timestamp: (date now | format date '%Y-%m-%d %H:%M:%S')"
290 echo "=== Volume Mount Status and Accessibility ==="
291 echo "Checking volume mount accessibility..."
293 # Check model volume mount
294 echo "Model volume mount status:"
295 if (ls /model | length) > 0 {
296 echo "✓ Model volume mounted successfully at /model"
297 echo $" Files found: (ls /model | length)"
299 echo "✗ Model volume mount failed or empty"
302 # Check fleet volume mount
303 echo "Fleet volume mount status:"
304 if (ls /repos/fleet-osm | length) > 0 {
305 echo "✓ Fleet volume mounted successfully at /repos/fleet-osm"
306 echo $" Files found: (ls /repos/fleet-osm | length)"
308 echo "✗ Fleet volume mount failed or empty"
311 # Check sw-catalogs volume mount
312 echo "SW-Catalogs volume mount status:"
313 if (ls /repos/sw-catalogs-osm | length) > 0 {
314 echo "✓ SW-Catalogs volume mounted successfully at /repos/sw-catalogs-osm"
315 echo $" Files found: (ls /repos/sw-catalogs-osm | length)"
317 echo "✗ SW-Catalogs volume mount failed or empty"
321 echo "=== Model Volume Contents and Structure ==="
322 echo "Model volume directory structure:"
324 ls /model -la | select name type size permissions | table
326 echo "Error accessing model volume contents"
330 echo "=== Required Model Files Validation ==="
331 # Check app_instance_model.yaml
332 if ("/model/app_instance_model.yaml" | path exists) {
333 echo "✓ app_instance_model.yaml found"
335 let file_size = (ls /model/app_instance_model.yaml | get size | first)
336 echo $" Size: ($file_size) bytes"
338 echo " Warning: Could not read file size"
341 echo "✗ app_instance_model.yaml missing"
344 # Check clear parameters
345 if ("/model/parameters/clear/environment.yaml" | path exists) {
346 echo "✓ Clear parameters file found"
348 let file_size = (ls /model/parameters/clear/environment.yaml | get size | first)
349 echo $" Size: ($file_size) bytes"
351 echo " Warning: Could not read file size"
354 echo "ℹ Clear parameters file missing (optional)"
357 # Check secret parameters
358 if ("/model/parameters/secret/environment.yaml" | path exists) {
359 echo "✓ Secret parameters file found"
361 let file_size = (ls /model/parameters/secret/environment.yaml | get size | first)
362 echo $" Size: ($file_size) bytes"
364 echo " Warning: Could not read file size"
367 echo "ℹ Secret parameters file missing (optional)"
370 echo "=== Model Content Analysis ==="
371 echo "App Instance Model (first 30 lines):"
373 open /model/app_instance_model.yaml | lines | first 30 | str join "\n"
375 echo "Error reading app_instance_model.yaml"
379 echo "Clear Parameters Content:"
381 open /model/parameters/clear/environment.yaml | to yaml
383 echo "Clear parameters not available"
387 echo "Secret Parameters Content (masked for security):"
389 if ("/model/parameters/secret/environment.yaml" | path exists) {
390 echo "Secret file exists - content masked for security"
392 echo "Secret parameters not available"
395 echo "Error checking secret parameters"
399 echo "=== Loaded Model Instance from Volume ==="
401 $model_instance | to yaml | lines | first 30 | str join "\n"
403 echo "Error loading model instance"
407 echo "=== Environment Parameters from Volume ==="
409 $environment | to yaml | lines | first 30 | str join "\n"
411 echo "Error loading environment"
415 echo "=== Repository Structure ==="
416 echo "Fleet repo contents:"
418 ls /repos/fleet-osm | select name type size | first 10 | table
420 echo "Error accessing fleet repository"
423 echo "SW-Catalogs repo contents:"
425 ls /repos/sw-catalogs-osm | select name type size | first 10 | table
427 echo "Error accessing sw-catalogs repository"
431 echo "=== Embedded Operations Validation ==="
432 echo "App Operations Library Status:"
434 help app | lines | first 10 | str join "\n"
436 echo "Error accessing app operations library"
440 echo "=== Dry Run Test ==="
441 echo "Testing command execution with volume-mounted data..."
443 echo $"Command to execute: {{inputs.parameters.command}}"
444 echo "✓ Command validation successful with volume-based data"
446 echo $"✗ Command validation failed: ($in)"
450 echo "=== Volume Permissions Check ==="
451 echo "Model volume permissions:"
453 ls -la /model | head -5 | each { |item| echo $" ($item.name): ($item.permissions)" } | str join "\n"
455 echo "Error checking model volume permissions"
459 echo "=== Debug Information Complete ==="
464 mountPath: /repos/fleet-osm
466 - name: sw-catalogs-volume
467 mountPath: /repos/sw-catalogs-osm
468 subPath: sw-catalogs-osm
469 # Mount secret volume when secret_name is provided
470 - name: secret-volume
471 mountPath: /model/parameters/secret
475 persistentVolumeClaim:
476 claimName: "{{inputs.parameters.model_volume_name}}"
478 persistentVolumeClaim:
479 claimName: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
480 - name: sw-catalogs-volume
481 persistentVolumeClaim:
482 claimName: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
483 - name: secret-volume
485 secretName: "{{inputs.parameters.secret_name}}"
488 # === PHASE 5: Application Operations ===
489 # This phase performs the actual create/update/delete operations on the application model
490 - - name: run-app-operation
491 when: "{{inputs.parameters.dry_run}} != true"
494 image: "{{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
495 args: ["{{inputs.parameters.command}}"] # Full command string to execute
497 # Mount model volume containing application data
500 # Mount Fleet repository for GitOps target
502 mountPath: /repos/fleet-osm
504 # Mount SW-Catalogs repository for application templates
505 - name: sw-catalogs-volume
506 mountPath: /repos/sw-catalogs-osm
507 subPath: sw-catalogs-osm
508 # Mount secret volume when secret_name is provided
509 - name: secret-volume
510 mountPath: /model/parameters/secret
514 persistentVolumeClaim:
515 claimName: "{{inputs.parameters.model_volume_name}}"
517 persistentVolumeClaim:
518 claimName: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
519 - name: sw-catalogs-volume
520 persistentVolumeClaim:
521 claimName: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
522 - name: secret-volume
524 secretName: "{{inputs.parameters.secret_name}}"
526 # Dry-run variant of the app operation for validation without changes
527 - name: run-app-operation-dry-run
528 when: "{{inputs.parameters.dry_run}} == true"
531 image: "{{inputs.parameters.osm_sdk_image_repository}}:{{inputs.parameters.osm_sdk_image_tag}}"
532 args: ["{{inputs.parameters.command}} --dry-run"] # Full command string with dry-run flag
534 # Same volume mounts as regular operation for consistency
538 mountPath: /repos/fleet-osm
540 - name: sw-catalogs-volume
541 mountPath: /repos/sw-catalogs-osm
542 subPath: sw-catalogs-osm
543 # Mount secret volume when secret_name is provided
544 - name: secret-volume
545 mountPath: /model/parameters/secret
549 persistentVolumeClaim:
550 claimName: "{{inputs.parameters.model_volume_name}}"
552 persistentVolumeClaim:
553 claimName: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
554 - name: sw-catalogs-volume
555 persistentVolumeClaim:
556 claimName: '{{steps.generate-sw-catalogs-volume-repo.outputs.parameters.pvc-name}}'
557 - name: secret-volume
559 secretName: "{{inputs.parameters.secret_name}}"
562 # === PHASE 7: GitOps Commit and Push ===
563 # Commit and push the generated application manifests to the Fleet repository
564 # This completes the GitOps workflow by updating the target repository with changes
565 - - name: push-to-fleet
568 template: git-commit-merge-push
574 value: "{{inputs.parameters.fleet_destination_folder}}"
575 - name: git_cred_secret
576 value: "{{inputs.parameters.git_fleet_cred_secret}}"
577 - name: git_volume_name
578 value: '{{steps.generate-fleet-volume-repo.outputs.parameters.pvc-name}}'
579 - name: commit_message
580 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]"
583 - name: contrib_branch
586 value: "{{inputs.parameters.dry_run}}"