{"id":28493061,"url":"https://github.com/hhftechnology/cloudpanel-api","last_synced_at":"2025-07-08T05:31:42.340Z","repository":{"id":272868719,"uuid":"917239999","full_name":"hhftechnology/cloudpanel-api","owner":"hhftechnology","description":"Cloudpanel API","archived":false,"fork":false,"pushed_at":"2025-01-17T13:49:45.000Z","size":107,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-08T09:07:22.633Z","etag":null,"topics":["api","cloudpanel"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hhftechnology.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-15T16:08:24.000Z","updated_at":"2025-01-17T13:49:46.000Z","dependencies_parsed_at":"2025-01-17T05:37:32.647Z","dependency_job_id":null,"html_url":"https://github.com/hhftechnology/cloudpanel-api","commit_stats":null,"previous_names":["hhftechnology/cloudpanel-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hhftechnology/cloudpanel-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fcloudpanel-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fcloudpanel-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fcloudpanel-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fcloudpanel-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hhftechnology","download_url":"https://codeload.github.com/hhftechnology/cloudpanel-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fcloudpanel-api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264200782,"owners_count":23571834,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","cloudpanel"],"created_at":"2025-06-08T09:07:23.405Z","updated_at":"2025-07-08T05:31:42.334Z","avatar_url":"https://github.com/hhftechnology.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CloudPanel API Structure\n\n```plaintext\ncloudpanel-api/\n├── .github/                      # GitHub specific files\n│   └── workflows/                # GitHub Actions workflows\n│       └── ci.yml\n│\n├── src/                         # Source code\n│   ├── config/                  # Configuration files\n│   │   ├── config.js           # Main configuration\n│   │   └── database.js         # Database configuration\n│   │\n│   ├── controllers/            # Route controllers\n│   │   ├── siteController.js\n│   │   ├── databaseController.js\n│   │   ├── userController.js\n│   │   ├── certificateController.js\n│   │   └── monitoringController.js\n│   │\n│   ├── middleware/             # Express middleware\n│   │   ├── auth.js            # API key authentication\n│   │   ├── validation.js      # Request validation\n│   │   ├── security.js        # Security middleware\n│   │   ├── logging.js         # Logging middleware\n│   │   └── errorHandler.js    # Error handling\n│   │\n│   ├── models/                # Database models\n│   │   ├── Site.js\n│   │   ├── Database.js\n│   │   ├── User.js\n│   │   ├── Certificate.js\n│   │   └── ApiKey.js\n│   │\n│   ├── routes/                # API routes\n│   │   ├── v1/               # API version 1\n│   │   │   ├── sites.js\n│   │   │   ├── databases.js\n│   │   │   ├── users.js\n│   │   │   ├── certificates.js\n│   │   │   └── monitoring.js\n│   │   └── index.js          # Route aggregator\n│   │\n│   ├── services/             # Business logic\n│   │   ├── siteService.js\n│   │   ├── databaseService.js\n│   │   ├── userService.js\n│   │   └── monitoringService.js\n│   │\n│   ├── utils/                # Utility functions\n│   │   ├── logger.js        # Logging utility\n│   │   ├── validation.js    # Input validation\n│   │   └── helpers.js       # Helper functions\n│   │\n│   ├── metrics/             # Monitoring metrics\n│   │   ├── prometheus.js\n│   │   └── collectors.js\n│   │\n│   └── app.js              # Express app setup\n│\n├── docker/                  # Docker related files\n│   ├── Dockerfile\n│   └── docker-compose.yml\n│\n├── config/                 # Configuration files\n│   ├── prometheus/\n│   │   └── prometheus.yml\n│   ├── grafana/\n│   │   └── datasources.yml\n│   └── loki/\n│       └── loki-config.yml\n│\n├── cloudpanel-scripts/               # Utility scripts\n│\n├── tests/                # Test files\n│   ├── unit/\n│   │   ├── controllers/\n│   │   ├── services/\n│   │   └── models/\n│   ├── integration/\n│   └── setup.js\n│\n├── docs/                 # Documentation\n│   ├── api/\n│   │   └── swagger.yaml\n│   ├── setup.md\n│   └── monitoring.md\n│\n├── .env.example         # Example environment variables\n├── .eslintrc.js        # ESLint configuration\n├── .prettierrc         # Prettier configuration\n├── .gitignore\n├── package.json\n└── README.md\n```\n\n## Key Explanations\n\n### `/src`\nContains all source code for the API. Organized by feature and responsibility.\n\n### `/src/controllers`\nHandle HTTP requests and responses. They use services for business logic.\n\n### `/src/services`\nContains business logic and database interactions.\n\n### `/src/middleware`\nExpress middleware for authentication, logging, etc.\n\n### `/src/models`\nDatabase models and schema definitions.\n\n### `/src/routes`\nAPI route definitions, versioned in `/v1` directory.\n\n### `/config`\nExternal service configurations (Prometheus, Grafana, etc.).\n\n### `/docker`\nDocker-related files for containerization.\n\n### `/tests`\nTest files organized by type (unit, integration).\n\n### `/docs`\nAPI documentation and setup guides.\n\n# CloudPanel API Documentation\n\n## Authentication\nAll API requests require an API key passed in the header:\n```\nX-API-Key: cp_your_api_key_here\n```\n\n## Endpoints\n\n### Sites\n\n#### GET /api/v1/sites\nLists all sites.\n\nResponse:\n```json\n{\n  \"sites\": [\n    {\n      \"id\": 1,\n      \"domainName\": \"example.com\",\n      \"type\": \"php\",\n      \"rootDirectory\": \"/home/user/htdocs/example.com\"\n    }\n  ]\n}\n```\n\n#### POST /api/v1/sites\nCreate a new site.\n\nRequest:\n```json\n{\n  \"domainName\": \"newsite.com\",\n  \"type\": \"php\",\n  \"rootDirectory\": \"/home/user/htdocs/newsite.com\",\n  \"phpVersion\": \"8.2\"\n}\n```\n\n### Databases\n\n#### GET /api/v1/databases\nLists all databases.\n\n#### POST /api/v1/databases\nCreate a new database.\n\nRequest:\n```json\n{\n  \"name\": \"mydb\",\n  \"siteId\": 1,\n  \"user\": {\n    \"username\": \"dbuser\",\n    \"password\": \"securepass\"\n  }\n}\n```\n\n### Users\n\n#### GET /api/v1/users\nLists all users (requires admin API key).\n\n#### POST /api/v1/users\nCreate a new user (requires admin API key).\n\nRequest:\n```json\n{\n  \"username\": \"newuser\",\n  \"email\": \"user@example.com\",\n  \"role\": \"user\"\n}\n```\n\n## Rate Limiting\n- 100 requests per 15 minutes per IP address\n- Status 429 returned when exceeded\n\n## Error Responses\n```json\n{\n  \"error\": \"Error message here\",\n  \"code\": \"ERROR_CODE\",\n  \"details\": {} // Optional additional information\n}\n```\n\nWhen someone makes a request to create a site through the API endpoint (e.g., POST /api/v1/sites), here's what happens:\n\nFirst, the API route handler in `/src/routes/v1/sites.js` receives the request:\n\n```javascript\nrouter.post('/', async (req, res) =\u003e {\n    try {\n        // Create an operation record in the database\n        const operationId = await db.run(`\n            INSERT INTO operations (\n                type, data, status, source, created_at\n            ) VALUES (\n                'site.create',\n                ?, \n                'pending',\n                'api',\n                datetime('now')\n            )\n        `, [JSON.stringify(req.body)]);\n\n        // Return immediate response with operation ID\n        res.status(202).json({\n            success: true,\n            operation_id: operationId,\n            message: 'Operation queued'\n        });\n    } catch (error) {\n        // Error handling...\n    }\n});\n```\n\nMeanwhile, i have two systemd services running continuously:\n\n1. The queue worker (`queue_worker.sh`), which checks for new operations:\n```bash\nwhile true; do\n    # Query for pending operations\n    pending_ops=$(sqlite3 /home/clp/htdocs/app/data/db.sq3 \"\n        SELECT id, type \n        FROM operations \n        WHERE status = 'pending' \n        AND source = 'api'\n        ORDER BY created_at ASC\n    \")\n    \n    if [[ -n \"$pending_ops\" ]]; then\n        # Process each operation...\n    fi\n    sleep 5\ndone\n```\n\n2. The status monitor (`status_monitor.sh`), which watches for problems:\n```bash\nwhile true; do\n    # Check for stuck or timed out operations\n    check_stuck_operations\n    check_timed_out_operations\n    sleep 60\ndone\n```\n\nSo when a site creation request comes in:\n\n1. API creates 'pending' operation in database\n2. Queue worker sees new operation within 5 seconds\n3. Queue worker runs appropriate script (e.g., `manage_site.sh create $operation_id`)\n4. Script processes operation and updates status to 'completed' or 'failed'\n5. Status monitor ensures nothing gets stuck\n\nThe client can poll the operation status endpoint to track progress:\n```javascript\nrouter.get('/operations/:id', async (req, res) =\u003e {\n    const operation = await db.get(`\n        SELECT status, error, result \n        FROM operations \n        WHERE id = ?\n    `, [req.params.id]);\n    \n    res.json({\n        success: true,\n        data: operation\n    });\n});\n```\n\nThis architecture gives us:\n- Immediate API responses (non-blocking)\n- Reliable operation processing\n- Status tracking\n- Error handling\n- Separation from UI operations\n\nStill working on\nUI API Script triger challange. The key is to create a distinction layer betien UI and API operations in CloudPanel.\n\nThe first step is to modify our core operation tracking in the database. When an operation comes in via the API, it should be tagged as an API operation. I can do this by adding a `source` column to our operations table:\n\n```sql\nALTER TABLE operations ADD COLUMN source VARCHAR(10) DEFAULT 'ui';\n```\n\nThen, I need to modify how our scripts check whether they should execute. the core database.sh script to include this check:\n\n```bash\n# Function to check if operation should be handled by scripts\nshould_handle_operation() {\n    local operation_id=$1\n    \n    local source=$(sqlite3 /home/clp/htdocs/app/data/db.sq3 \"\n        SELECT source \n        FROM operations \n        WHERE id = $operation_id\n    \")\n    \n    # Only handle operations that came from the API\n    [[ \"$source\" == \"api\" ]]\n}\n```\n\nNow I can modify each of my handler scripts to use this check. For example, in manage_site.sh:\n\n```bash\n# Main execution function\nmain() {\n    OPERATION_ID=$2\n    local operation=$1\n    \n    # First check if i should handle this operation\n    if ! should_handle_operation $OPERATION_ID; then\n        log_message \"Operation $OPERATION_ID is not an API operation - skipping\"\n        exit 0\n    fi\n    \n    # Rest of the script continues as before...\n```\n\nFor the API side, i need to ensure operations are properly tagged. When creating an operation through the API, i'll set the source:\n\n```bash\ncreate_operation() {\n    local type=$1\n    local data=$2\n    \n    sqlite3 /home/clp/htdocs/app/data/db.sq3 \"\n        INSERT INTO operations (\n            type, data, status, source, created_at\n        ) VALUES (\n            '$type',\n            '$data',\n            'pending',\n            'api',\n            datetime('now')\n        )\n    \"\n}\n```\n\nThis approach allows UI operations to continue using CloudPanel's built-in functionality while API operations go through our script system. This separation solves my chalanges:\n\n1. No interference with existing UI operations\n2. Clear tracking of operation sources\n3. Easy to maintain and debug\n4. No risk of duplicate operations\n\nThe queue worker and status monitor will naturally only process API operations since they'll inherit this check through the core database functions.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhftechnology%2Fcloudpanel-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhhftechnology%2Fcloudpanel-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhftechnology%2Fcloudpanel-api/lists"}