portainer-mcp/create_nginx_stack.py
Adolfo Delorenzo 7a1abbe243 feat: add Portainer Edge MCP server
- Implement comprehensive edge computing functionality
- Add edge environment management (list, get, status, generate keys)
- Add edge stack operations (list, get, create, update, delete)
- Add edge group management (list, get, create, update, delete)
- Add edge job scheduling (list, get, create, delete)
- Add edge settings configuration (get, update)
- Create test scripts for edge API validation
- Add comprehensive README documentation for edge server
- Include nginx stack creation script from earlier testing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 23:59:56 -03:00

131 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""Create nginx02 stack from Git repository"""
import aiohttp
import asyncio
import json
import sys
# Configuration
PORTAINER_URL = "https://partner.portainer.live"
PORTAINER_API_KEY = "ptr_uMqreULEo44qvuszgG8oZWdjkDx3K9HBXSmjd+F/vDE="
# Stack configuration
STACK_NAME = "nginx02"
ENVIRONMENT_ID = 6 # docker03
REPOSITORY_URL = "https://git.oe74.net/adelorenzo/portainer-yaml"
REPOSITORY_REF = "main" # or master
COMPOSE_PATH = "nginx-cmpose.yaml"
GIT_USERNAME = "adelorenzo"
GIT_PASSWORD = "dimi2014"
def create_stack_from_git():
"""Create a stack from Git repository"""
# Build request data
data = {
"Name": STACK_NAME,
"EndpointId": ENVIRONMENT_ID,
"GitConfig": {
"URL": REPOSITORY_URL,
"ReferenceName": REPOSITORY_REF,
"ComposeFilePathInRepository": COMPOSE_PATH,
"Authentication": {
"Username": GIT_USERNAME,
"Password": GIT_PASSWORD
}
}
}
# Headers
headers = {
"X-API-Key": PORTAINER_API_KEY,
"Content-Type": "application/json"
}
# API endpoint
url = f"{PORTAINER_URL}/api/stacks"
print(f"Creating stack '{STACK_NAME}' from Git repository...")
print(f"Repository: {REPOSITORY_URL}")
print(f"Compose file: {COMPOSE_PATH}")
print(f"Environment ID: {ENVIRONMENT_ID}")
try:
response = requests.post(url, json=data, headers=headers)
if response.status_code == 200 or response.status_code == 201:
result = response.json()
print(f"\n✅ Stack created successfully!")
print(f"Stack ID: {result['Id']}")
print(f"Stack Name: {result['Name']}")
return result
else:
print(f"\n❌ Error creating stack: {response.status_code}")
print(f"Response: {response.text}")
# Try to parse error message
try:
error_data = response.json()
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
except Exception as e:
print(f"\n❌ Exception occurred: {str(e)}")
return None
def list_existing_stacks():
"""List existing stacks to check for references"""
headers = {
"X-API-Key": PORTAINER_API_KEY
}
url = f"{PORTAINER_URL}/api/stacks"
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
stacks = response.json()
print("\n📚 Existing stacks:")
for stack in stacks:
if stack.get("EndpointId") == ENVIRONMENT_ID:
print(f" - {stack['Name']} (ID: {stack['Id']})")
if stack.get("GitConfig"):
print(f" Git: {stack['GitConfig']['URL']}")
print(f" Path: {stack['GitConfig'].get('ComposeFilePathInRepository', 'N/A')}")
return stacks
else:
print(f"Error listing stacks: {response.status_code}")
return []
except Exception as e:
print(f"Exception listing stacks: {str(e)}")
return []
if __name__ == "__main__":
# First, list existing stacks
print("Checking existing stacks on environment docker03...")
existing_stacks = list_existing_stacks()
# Check if stack already exists
stack_exists = any(s['Name'] == STACK_NAME and s.get('EndpointId') == ENVIRONMENT_ID for s in existing_stacks)
if stack_exists:
print(f"\n⚠️ Stack '{STACK_NAME}' already exists on this environment!")
response = input("Do you want to continue anyway? (y/n): ")
if response.lower() != 'y':
print("Aborting...")
sys.exit(0)
# Create the stack
print("\n" + "="*50)
result = create_stack_from_git()
if result:
print("\n🎉 Stack deployment completed!")
else:
print("\n😞 Stack deployment failed!")