#!/usr/bin/env python3 """Test creating a stack with GitOps enabled""" import asyncio import aiohttp import json import sys # Configuration PORTAINER_URL = "https://partner.portainer.live" PORTAINER_API_KEY = "ptr_uMqreULEo44qvuszgG8oZWdjkDx3K9HBXSmjd+F/vDE=" # Stack configuration STACK_NAME = "nginx03-gitops" ENVIRONMENT_ID = 6 # docker03 REPOSITORY_URL = "https://git.oe74.net/adelorenzo/portainer-yaml" REPOSITORY_REF = "main" COMPOSE_PATH = "docker-compose.yml" async def create_stack_with_gitops(): """Create a stack with GitOps enabled from the start""" # Build request data data = { "name": STACK_NAME, "repositoryURL": REPOSITORY_URL, "repositoryReferenceName": REPOSITORY_REF, "composeFilePathInRepository": COMPOSE_PATH, "repositoryAuthentication": False, "autoUpdate": { "interval": "5m", "forcePullImage": True, "forceUpdate": False } } # Headers headers = { "X-API-Key": PORTAINER_API_KEY, "Content-Type": "application/json" } # API endpoint endpoint = f"{PORTAINER_URL}/api/stacks/create/standalone/repository?endpointId={ENVIRONMENT_ID}" print(f"Creating stack '{STACK_NAME}' with GitOps enabled...") print(f"Repository: {REPOSITORY_URL}") print(f"Compose file: {COMPOSE_PATH}") print(f"Environment ID: {ENVIRONMENT_ID}") print(f"GitOps: Enabled (polling every 5m)") try: async with aiohttp.ClientSession() as session: async with session.post(endpoint, json=data, headers=headers) as response: response_text = await response.text() if response.status in [200, 201]: result = json.loads(response_text) print(f"\nāœ… Stack created successfully!") print(f"Stack ID: {result['Id']}") print(f"Stack Name: {result['Name']}") # Check GitOps status if result.get("AutoUpdate"): print(f"\nšŸ”„ GitOps Status:") auto_update = result["AutoUpdate"] print(f" Enabled: Yes") print(f" Interval: {auto_update.get('Interval', 'N/A')}") print(f" Force Pull Image: {auto_update.get('ForcePullImage', False)}") print(f" Force Update: {auto_update.get('ForceUpdate', False)}") else: print(f"\nāš ļø GitOps is not enabled on the created stack") return result else: print(f"\nāŒ Error creating stack: {response.status}") print(f"Response: {response_text}") # Try to parse error message try: error_data = json.loads(response_text) if "message" in error_data: print(f"Error message: {error_data['message']}") elif "details" in error_data: print(f"Error details: {error_data['details']}") except: pass return None except Exception as e: print(f"\nāŒ Exception occurred: {str(e)}") return None async def check_stack_gitops(stack_id): """Check if GitOps is enabled on a stack""" headers = { "X-API-Key": PORTAINER_API_KEY } endpoint = f"{PORTAINER_URL}/api/stacks/{stack_id}" try: async with aiohttp.ClientSession() as session: async with session.get(endpoint, headers=headers) as response: if response.status == 200: result = await response.json() print(f"\nšŸ“š Stack Details:") print(f"Name: {result['Name']}") print(f"ID: {result['Id']}") if result.get("GitConfig"): print(f"\nšŸ”— Git Configuration:") git = result["GitConfig"] print(f" Repository: {git['URL']}") print(f" Reference: {git['ReferenceName']}") print(f" Path: {git.get('ConfigFilePath', 'N/A')}") if result.get("AutoUpdate"): print(f"\nšŸ”„ GitOps Configuration:") auto = result["AutoUpdate"] print(f" Enabled: Yes") print(f" Interval: {auto.get('Interval', 'N/A')}") print(f" Force Pull Image: {auto.get('ForcePullImage', False)}") print(f" Force Update: {auto.get('ForceUpdate', False)}") if auto.get("Webhook"): print(f" Webhook: Enabled") else: print(f"\nāŒ GitOps: Disabled") return result else: print(f"Error getting stack details: {response.status}") return None except Exception as e: print(f"Exception getting stack details: {str(e)}") return None async def main(): print("=" * 60) print("Testing Portainer Stack Creation with GitOps") print("=" * 60) # Create the stack with GitOps result = await create_stack_with_gitops() if result: print("\n" + "=" * 60) print("Verifying GitOps configuration...") print("=" * 60) # Wait a moment for the stack to be fully created await asyncio.sleep(2) # Check the stack details await check_stack_gitops(result["Id"]) print("\nšŸŽ‰ Test completed!") else: print("\nšŸ˜ž Test failed!") if __name__ == "__main__": asyncio.run(main())