Add cloud-init scripts to the global search navigation routes, making
them discoverable via the quick search (Cmd+K / Ctrl+K).
Changes:
- Added dedicated "Cloud-Init Scripts" navigation entry
- Searchable via: cloud-init, scripts, cloud init, cloudinit,
initialization, startup, server setup
- Updated Security entry to include cloud-init in search terms
- Links to /security/cloud-init-scripts route
Users can now quickly navigate to cloud-init script management by
typing "cloud-init" or related terms in global search.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix multiple UI/UX issues with cloud-init scripts management:
1. Fix card styling - Remove purple box background, use simple border
- Changed from .box class to inline flex/border styling
- Matches cloud provider tokens styling pattern
2. Remove script preview section
- Preview was taking too much space and looked cluttered
- Users can edit to see full script content
3. Make edit modal full width
- Added fullWidth attribute to x-modal-input component
- Provides better editing experience for long scripts
4. Fix fields clearing after update
- Fields were being reset even in edit mode
- Now only reset fields when creating new script
- Edit mode preserves values after save
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive cloud-init script management interface in the Security
section, allowing users to create, edit, delete, and reuse cloud-init
scripts across their team.
New Components:
- CloudInitScripts: Main listing page with grid view of scripts
- CloudInitScriptForm: Modal form for create/edit operations
Features:
- Create new cloud-init scripts with name and content
- Edit existing scripts
- Delete scripts with confirmation (requires typing script name)
- View script preview (first 200 characters)
- Scripts are encrypted in database
- Full authorization using CloudInitScriptPolicy
- Real-time updates via Livewire events
UI Location:
- Added to Security section nav: /security/cloud-init-scripts
- Positioned between Cloud Tokens and API Tokens
- Follows existing security UI patterns
Files Created:
- app/Livewire/Security/CloudInitScripts.php
- app/Livewire/Security/CloudInitScriptForm.php
- resources/views/livewire/security/cloud-init-scripts.blade.php
- resources/views/livewire/security/cloud-init-script-form.blade.php
Files Modified:
- routes/web.php - Added route
- resources/views/components/security/navbar.blade.php - Added nav link
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add cloud-init script fields to the resetSelection() method that's
called when the modal is closed. This ensures a clean slate when
reopening the "Connect a Hetzner Server" view.
Fields reset:
- cloud_init_script
- save_cloud_init_script
- cloud_init_script_name
- selected_cloud_init_script_id
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add detailed ray logging to track exactly what is being sent to Hetzner's
API and what response is received. This will help debug cloud-init script
integration and verify that user_data is properly included in the request.
Logs include:
- Request endpoint and full params object
- Complete API response
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
1. Remove description field from cloud-init scripts
- Updated migration to remove description column
- Updated model to remove description from fillable array
2. Redesign script name input layout
- Move script name input next to checkbox (always visible)
- Remove conditional rendering - input always shown
- Use placeholder instead of label for cleaner look
3. Fix dropdown type error
- Replace wire:change event with wire:model.live
- Use updatedSelectedCloudInitScriptId() lifecycle hook
- Add "disabled" attribute to placeholder option
- Properly handle empty string vs null in type casting
4. Improve validation
- Require both script content AND name for saving
- Remove description validation rule
- Add selected_cloud_init_script_id validation
5. Auto-populate name when loading saved script
- When user selects saved script, auto-fill the name field
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds the ability to use cloud-init scripts when creating Hetzner servers through the integration. Users can write custom scripts that will be executed during server initialization, and optionally save these scripts at the team level for future reuse.
Key features:
- Textarea field for entering cloud-init scripts (bash or cloud-config YAML)
- Checkbox to save scripts for later use at team level
- Dropdown to load previously saved scripts
- Scripts are encrypted in the database
- Full validation and authorization checks
- Comprehensive unit and feature tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Display the monthly cost on the "Buy & Create Server" button
to give users clear visibility of the price before purchasing.
- Add computed property to calculate selected server's monthly price
- Update button text to show price dynamically (e.g., "€12.99/mo")
- Add tests for price formatting and edge cases
- Price updates reactively when user changes server type
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add support for configuring IPv4 and IPv6 public network interfaces when creating servers through the Hetzner integration. Users can now enable or disable IPv4 and IPv6 independently, with both enabled by default.
Features:
- Added enable_ipv4 and enable_ipv6 checkboxes in the server creation form
- Both options are enabled by default as per Hetzner best practices
- IPv4 is preferred when both are enabled
- Fallback to IPv6 when only IPv6 is enabled
- Proper validation and error handling for network configuration
- Comprehensive test coverage for IP address selection logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replaced the inline query for fetching environments in GlobalSearch with a new static method `ownedByCurrentTeam` in the Environment model, enhancing code readability and maintainability.
- This change simplifies the logic for retrieving environments associated with the current team, promoting better organization of query logic within the model.
- Introduced a comprehensive set of navigation routes for quick access to key sections such as Dashboard, Servers, Projects, and more.
- Enhanced the search functionality to include a 'new' prefix for creating resources directly from the search input.
- Improved UI elements for search results, ensuring better visibility and interaction.
- Modified the redirect route after project resource creation to include the UUID of the production environment, ensuring users are directed to the correct resource index page.
- This change enhances navigation and improves user experience by providing direct access to the relevant environment resources.
- Introduced a new create mode in the global search component, allowing users to initiate the creation of resources directly from the search input.
- Implemented logic to detect specific resource types based on user input, enabling quick access to creation modals for projects, servers, teams, storage, private keys, and GitHub apps.
- Updated the UI to display a list of creatable items when in create mode, improving user experience and accessibility for resource management.
- Added necessary modals for each resource type to facilitate the creation process seamlessly.
- Added logic to determine if the user can create resources for each project and generate the corresponding route for adding resources based on the project's first environment.
- Updated the project index view to display the new resource creation option alongside existing project settings.
- Adjusted various views to include a margin-top adjustment for better layout consistency.
- Updated the build_logs_url to use the correct environment UUID instead of the environment name, ensuring accurate links to deployment logs.
- This change improves the reliability of the deployment notification system by directing users to the correct log location.
- Wrapped the storage settings submission process in a database transaction to ensure data integrity.
- Added connection testing within the transaction to verify settings before finalizing the save.
- Enhanced error handling by refreshing the model state after a rollback, ensuring the UI reflects the latest database values.
- Dispatch success event upon successful update and verification of storage settings.
- Introduced a new notification class, BackupSuccessWithS3Warning, to alert users when local backups succeed but S3 uploads fail.
- Updated DatabaseBackupJob to track local backup success and handle S3 upload errors, improving error reporting and user notifications.
- Modified ScheduledDatabaseBackupExecution model to include a new s3_uploaded boolean field for tracking S3 upload status.
- Adjusted views and validation logic to reflect changes in backup execution status and S3 handling.
- Added tests to ensure the new s3_uploaded column is correctly implemented and validated.
- Updated the should_skip_build method to save runtime environment variables even when the build step is skipped, ensuring that the latest environment settings are preserved.
- Enhanced logging in prepare_builder_image to differentiate between the first attempt and subsequent attempts, improving clarity in deployment logs.
- Implemented a check for the NIXPACKS_NODE_VERSION variable in the ApplicationDeploymentJob.
- Added log entries to notify users when NIXPACKS_NODE_VERSION is not set, indicating that Node.js 18 will be used by default, which is EOL.
- Provided guidance on how to override the default version by setting NIXPACKS_NODE_VERSION in environment variables.
- Updated the base_directory property to default to '/' for better compatibility with Docker setups.
- Included base_directory in the submit method's application array to ensure it is correctly passed during submission, enhancing the functionality of the GithubPrivateRepository component.
- Refactored the DatabaseBackupJob to replace instances of backup->uuid with backup_log_uuid for consistency in container naming.
- Ensured that all related Docker commands and processes reference the updated backup_log_uuid, improving clarity and reducing potential errors during backup operations.
- Added cache clearing for environment variables and their preview after a new variable is added to ensure the UI reflects the latest data.
- Updated the refreshEnvs method to include cache clearing, enhancing the responsiveness of the environment variable display.
- Added a new function to extract custom proxy commands from existing Traefik configurations before regenerating the proxy configuration.
- Updated the proxy configuration generation logic to include these custom commands, ensuring they are preserved during regeneration.
- Introduced unit tests to validate the extraction of custom commands and handle various scenarios, including invalid YAML and different proxy types.